gitlab-qa 7.7.3 → 7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d85e04e5802e15ef3b529ca3706e9fa1824029447bec5921c7648bba41257ad
4
- data.tar.gz: 19fd7b127dc987528d7aebafa62c82fe13a495eb6dc789bcc86ef7c535dc770a
3
+ metadata.gz: a57eadb5d0c8b13166ba80108c3c183299097ff4f90a39080df27216bdf1eabf
4
+ data.tar.gz: ff74b7e345f0c8bec66f0fe9ce0d6688375a3cd4de6fdc3dfd1db027f0e6a0fc
5
5
  SHA512:
6
- metadata.gz: 33a8d10016bef96fc1b947e8d9db5671c835c714f1511a989a3c9b4c75e12bee433559140844ba7ae78c9bbba49560b0e9dee6b890765b7fb565a17a4b50b133
7
- data.tar.gz: 6656512bcf01fbb980ef4cf91b64ab78a8b8c0841eda4e4fa7389059259cd96eaeccf0f8131cbfb3328b71c1842a17731f6444f3bb3b6ae17d2d14435c1b3f87
6
+ metadata.gz: 44fbe3b8d2f2e17a0e2614d0e55a6445751de96b7fec209f71bca58ddcaeed7105c5d8d697ea855111e9d35f4c387a4ccd6bc7260085f4d50703784f0cb07b25
7
+ data.tar.gz: 72ff7585e4be89bfe42f210a864b775195c0e2dc9d47da2d5bf6c54406684c02faaf6e8fda6ea7e70d3f0f080e3213b845b8866830879b6956cfb8a57146c92c
@@ -196,7 +196,7 @@ module Gitlab
196
196
  if testcase && !passed
197
197
  # Workaround for reducing system notes on testcase issues
198
198
  # The first regex extracts the link to the issues list page from a link to a single issue show page by removing the issue id.
199
- "[#{text}](#{testcase.match(%r{[\s\S]+\/[^\/\d]+})}?state=opened&search=#{encoded_text}) (testcase_id=#{testcase.match(/\d+/)})"
199
+ "[#{text}](#{testcase.match(%r{[\s\S]+\/[^\/\d]+})}?state=opened&search=#{encoded_text})"
200
200
  else
201
201
  text
202
202
  end
@@ -49,7 +49,7 @@ module Gitlab
49
49
  select ||= :itself
50
50
 
51
51
  handle_gitlab_client_exceptions do
52
- return [Gitlab.issue(project, iid)] if iid
52
+ return [Gitlab.issue(project, iid)].select(&select) if iid
53
53
 
54
54
  Gitlab.issues(project, options)
55
55
  .auto_paginate
@@ -63,8 +63,8 @@ module Gitlab
63
63
  end
64
64
  end
65
65
 
66
- def create_issue(title:, description:, labels:)
67
- attrs = { description: description, labels: labels }
66
+ def create_issue(title:, description:, labels:, issue_type: 'issue')
67
+ attrs = { issue_type: issue_type, description: description, labels: labels }
68
68
 
69
69
  handle_gitlab_client_exceptions do
70
70
  Gitlab.create_issue(project, title, attrs)
@@ -4,10 +4,10 @@ module Gitlab
4
4
  module QA
5
5
  module Report
6
6
  class GitlabIssueDryClient < GitlabIssueClient
7
- def create_issue(title:, description:, labels:)
7
+ def create_issue(title:, description:, labels:, issue_type: 'issue')
8
8
  attrs = { description: description, labels: labels }
9
9
 
10
- puts "The following issue would have been created:"
10
+ puts "The following #{issue_type} would have been created:"
11
11
  puts "project: #{project}, title: #{title}, attrs: #{attrs}"
12
12
  end
13
13
 
@@ -150,10 +150,10 @@ module Gitlab
150
150
  end
151
151
 
152
152
  def new_issue_labels(test)
153
- NEW_ISSUE_LABELS + up_to_date_labels(test: test)
153
+ up_to_date_labels(test: test, new_labels: NEW_ISSUE_LABELS)
154
154
  end
155
155
 
156
- def up_to_date_labels(test:, issue: nil)
156
+ def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
157
157
  super << pipeline_name_label
158
158
  end
159
159
 
@@ -88,17 +88,18 @@ module Gitlab
88
88
  issue&.labels&.to_set || Set.new
89
89
  end
90
90
 
91
- def update_labels(issue, test)
92
- new_labels = up_to_date_labels(test: test, issue: issue)
91
+ def update_labels(issue, test, new_labels = Set.new)
92
+ labels = up_to_date_labels(test: test, issue: issue, new_labels: new_labels)
93
93
 
94
- return if issue_labels(issue) == new_labels
94
+ return if issue_labels(issue) == labels
95
95
 
96
- gitlab.edit_issue(iid: issue.iid, options: { labels: new_labels.to_a })
96
+ gitlab.edit_issue(iid: issue.iid, options: { labels: labels.to_a })
97
97
  end
98
98
 
99
- def up_to_date_labels(test:, issue: nil)
99
+ def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
100
100
  labels = issue_labels(issue)
101
- labels << "Enterprise Edition" if ee_test?(test)
101
+ labels |= new_labels
102
+ ee_test?(test) ? labels << "Enterprise Edition" : labels.delete("Enterprise Edition")
102
103
  quarantine_job? ? labels << "quarantine" : labels.delete("quarantine")
103
104
 
104
105
  labels
@@ -10,6 +10,8 @@ module Gitlab
10
10
  class ResultsInIssues < ReportAsIssue
11
11
  private
12
12
 
13
+ RESULTS_SECTION_TEMPLATE = "\n\n### DO NOT EDIT BELOW THIS LINE\n\nActive and historical test results:"
14
+
13
15
  def run!
14
16
  puts "Reporting test results in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
15
17
 
@@ -17,7 +19,7 @@ module Gitlab
17
19
  puts "Reporting tests in #{test_results.path}"
18
20
 
19
21
  test_results.each do |test|
20
- report_test(test)
22
+ report_test(test) unless test.skipped
21
23
  end
22
24
 
23
25
  test_results.write
@@ -27,56 +29,135 @@ module Gitlab
27
29
  def report_test(test)
28
30
  puts "Reporting test: #{test.file} | #{test.name}"
29
31
 
30
- issue = find_issue(test)
32
+ testcase = find_testcase(test) || create_testcase(test)
33
+ test.testcase ||= testcase.web_url.sub('/issues/', '/quality/test_cases/')
34
+
35
+ issue = find_issue_by_iid(testcase, test)
36
+
37
+ unless issue
38
+ puts "No valid issue link found"
39
+ issue = find_or_create_issue(test)
40
+
41
+ add_issue_to_testcase(testcase, issue)
42
+ puts "Added issue #{issue.web_url} to testcase #{testcase.web_url}"
43
+ end
44
+
45
+ update_labels(testcase, test)
46
+ update_issue(issue, test)
47
+ end
48
+
49
+ def find_testcase(test)
50
+ iid = iid_from_testcase_url(test.testcase)
51
+
52
+ testcases = search_issues(test: test, issue_type: 'test_case', iid: iid)
53
+
54
+ warn(%(Test case url "#{test.testcase}" not valid)) if iid && testcases.blank?
55
+
56
+ warn(%(Too many test cases found with the file path "#{test.file}" and name "#{test.name}")) if testcases&.many?
57
+
58
+ testcases.first
59
+ end
60
+
61
+ def create_testcase(test)
62
+ title = title_from_test(test)
63
+ puts "Creating test case '#{title}' ..."
64
+
65
+ gitlab.create_issue(
66
+ title: title,
67
+ description: new_testcase_description(test),
68
+ labels: new_issue_labels(test),
69
+ issue_type: 'test_case'
70
+ )
71
+ end
72
+
73
+ def iid_from_testcase_url(url)
74
+ return warn(%(Please update #{url} to test case url")) if url&.include?('/-/issues/')
75
+
76
+ url && url.split('/').last.to_i
77
+ end
78
+
79
+ def new_testcase_description(test)
80
+ "#{new_issue_description(test)}#{RESULTS_SECTION_TEMPLATE}"
81
+ end
82
+
83
+ def issue_iid_from_testcase(testcase)
84
+ results = testcase.description.partition(RESULTS_SECTION_TEMPLATE).last if testcase.description.include?(RESULTS_SECTION_TEMPLATE)
85
+
86
+ return puts "No issue link found" unless results
87
+
88
+ issue_iid = results.split('/').last
89
+
90
+ issue_iid&.to_i
91
+ end
92
+
93
+ def find_or_create_issue(test)
94
+ issue = find_issue(test, 'issue')
31
95
 
32
96
  if issue
33
97
  puts "Found existing issue: #{issue.web_url}"
34
98
  else
35
- # Don't create new issues for skipped tests
36
- return if test.skipped
37
-
38
99
  issue = create_issue(test)
39
100
  puts "Created new issue: #{issue.web_url}"
40
101
  end
41
102
 
42
- test.testcase ||= issue.web_url
103
+ issue
104
+ end
43
105
 
44
- labels_updated = update_labels(issue, test)
45
- note_posted = note_status(issue, test)
106
+ def find_issue_by_iid(testcase, test)
107
+ iid = issue_iid_from_testcase(testcase)
46
108
 
47
- if labels_updated || note_posted
48
- puts "Issue updated."
49
- else
50
- puts "Test passed, no update needed."
51
- end
109
+ return unless iid
110
+
111
+ issues = search_issues(test: test, issue_type: 'issue', iid: iid)
112
+
113
+ warn(%(Issue iid "#{iid}" not valid)) if issues.empty?
114
+
115
+ issues.first
52
116
  end
53
117
 
54
- def find_issue(test)
55
- title = title_from_test(test)
56
- issues =
57
- gitlab.find_issues(
58
- iid: iid_from_testcase_url(test.testcase),
59
- options: { search: search_term(test) }) do |issue|
60
- issue.state == 'opened' && issue.title.strip == title
61
- end
118
+ def find_issue(test, issue_type)
119
+ issues = search_issues(test: test, issue_type: 'issue')
62
120
 
63
121
  warn(%(Too many issues found with the file path "#{test.file}" and name "#{test.name}")) if issues.many?
64
122
 
65
123
  issues.first
66
124
  end
67
125
 
126
+ def add_issue_to_testcase(testcase, issue)
127
+ results_section = testcase.description.include?(RESULTS_SECTION_TEMPLATE) ? '' : RESULTS_SECTION_TEMPLATE
128
+
129
+ gitlab.edit_issue(iid: testcase.iid, options: { description: (testcase.description + results_section + "\n\n#{issue.web_url}") })
130
+ end
131
+
132
+ def update_issue(issue, test)
133
+ new_labels = issue_labels(issue)
134
+ new_labels |= ['Testcase Linked']
135
+
136
+ labels_updated = update_labels(issue, test, new_labels)
137
+ note_posted = note_status(issue, test)
138
+
139
+ if labels_updated || note_posted
140
+ puts "Issue updated."
141
+ else
142
+ puts "Test passed, no update needed."
143
+ end
144
+ end
145
+
68
146
  def new_issue_labels(test)
69
- %w[status::automated]
147
+ ['Quality', "devops::#{test.stage}", 'status::automated']
70
148
  end
71
149
 
72
- def up_to_date_labels(test:, issue: nil)
150
+ def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
73
151
  labels = super
152
+ labels |= new_issue_labels(test).to_set
74
153
  labels.delete_if { |label| label.start_with?("#{pipeline}::") }
75
154
  labels << (test.failures.empty? ? "#{pipeline}::passed" : "#{pipeline}::failed")
76
155
  end
77
156
 
78
- def iid_from_testcase_url(url)
79
- url && url.split('/').last.to_i
157
+ def search_issues(test:, issue_type:, iid: nil)
158
+ gitlab.find_issues(iid: iid, options: { search: search_term(test) }) do |issue|
159
+ issue.state == 'opened' && issue.issue_type == issue_type && issue.title.strip == title_from_test(test)
160
+ end
80
161
  end
81
162
 
82
163
  def search_term(test)
@@ -87,10 +87,8 @@ module Gitlab
87
87
  Gitlab::QA::Report::RelateFailureIssue.new(**report_options).invoke!
88
88
 
89
89
  elsif report_options.delete(:report_in_issues)
90
- # Temporarily disable reporting while we switch to more efficient use of test cases and issues.
91
- # report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
92
- # Gitlab::QA::Report::ResultsInIssues.new(**report_options).invoke!
93
- puts "Reporting temporarily disabled. See https://gitlab.com/gitlab-org/gitlab-qa/-/issues/639"
90
+ report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
91
+ Gitlab::QA::Report::ResultsInIssues.new(**report_options).invoke!
94
92
 
95
93
  elsif report_options.delete(:generate_test_session)
96
94
  report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module QA
3
- VERSION = '7.7.3'.freeze
3
+ VERSION = '7.8.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-qa
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.7.3
4
+ version: 7.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab Quality