gitlab-qa 7.7.3 → 7.8.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: 4d85e04e5802e15ef3b529ca3706e9fa1824029447bec5921c7648bba41257ad
4
- data.tar.gz: 19fd7b127dc987528d7aebafa62c82fe13a495eb6dc789bcc86ef7c535dc770a
3
+ metadata.gz: c415d54da820d67fa1544a1ffaefaf913f27090c6c07fa1f06c02797bd8756d3
4
+ data.tar.gz: 43ad1f640c478c666658e503fa84b77e9a3bcfaa5c69d7d5d2ae4151e34c7adc
5
5
  SHA512:
6
- metadata.gz: 33a8d10016bef96fc1b947e8d9db5671c835c714f1511a989a3c9b4c75e12bee433559140844ba7ae78c9bbba49560b0e9dee6b890765b7fb565a17a4b50b133
7
- data.tar.gz: 6656512bcf01fbb980ef4cf91b64ab78a8b8c0841eda4e4fa7389059259cd96eaeccf0f8131cbfb3328b71c1842a17731f6444f3bb3b6ae17d2d14435c1b3f87
6
+ metadata.gz: bce89411537a6398b5168ecd32bbea3e8996173e07ef16bd4142c70e3c9cdf14110fe7d1b9dd35feaae37809068e255ced355d804c331a0f43431b47de92f787
7
+ data.tar.gz: 6c159684288d094f6266ea427f6320611b724f823f8ebab216a5139817c047fc1c99602b742a51d9467b38348f89d628b2995ea81ad722ed2229d6d089d0952a
@@ -74,6 +74,10 @@ All environment variables used by GitLab QA should be defined in [`lib/gitlab/qa
74
74
  | `QA_SLOW_CONNECTION_THROUGHPUT_KBPS` | `32` | The maximum throughput (in kbps) of the simulated slow connection. | No|
75
75
  | `QA_SKIP_PULL` | `false` | Set to `true` to skip pulling docker images (e.g., to use one you built locally). | No|
76
76
  | `QA_GENERATE_ALLURE_REPORT` | `false` | When running on CI, set to `true` to generate allure reports | No|
77
+ | `QA_EXPORT_TEST_METRICS` | `true` | When running on CI, set to `true` to export test metrics to influxdb | No|
78
+ | `QA_INFLUXDB_URL` |- | Influxdb url for test metrics reporting | No|
79
+ | `QA_INFLUXDB_TOKEN` |- | Influxdb token for test metrics reporting | No|
80
+ | `QA_RUN_TYPE` |- | QA run type like `staging-full`, `canary`, `production` etc. Used in test metrics reporting | No|
77
81
  | `GITHUB_USERNAME` |- | Username for authenticating with GitHub. | No|
78
82
  | `GITHUB_PASSWORD` |- | Password for authenticating with GitHub. | No|
79
83
  | `GITLAB_QA_LOOP_RUNNER_MINUTES` | `1` | Minutes to run and repeat a spec while using the '--loop' option; default value is 1 minute. | No|
@@ -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,138 @@ 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
+ if iid && testcases.blank?
55
+ warn(%(Test case url "#{test.testcase}" not valid))
56
+ testcases = search_issues(test: test, issue_type: 'test_case')
57
+ end
58
+
59
+ warn(%(Too many test cases found with the file path "#{test.file}" and name "#{test.name}")) if testcases&.many?
60
+
61
+ testcases.first
62
+ end
63
+
64
+ def create_testcase(test)
65
+ title = title_from_test(test)
66
+ puts "Creating test case '#{title}' ..."
67
+
68
+ gitlab.create_issue(
69
+ title: title,
70
+ description: new_testcase_description(test),
71
+ labels: new_issue_labels(test),
72
+ issue_type: 'test_case'
73
+ )
74
+ end
75
+
76
+ def iid_from_testcase_url(url)
77
+ return warn(%(\nPlease update #{url} to test case url")) if url&.include?('/-/issues/')
78
+
79
+ url && url.split('/').last.to_i
80
+ end
81
+
82
+ def new_testcase_description(test)
83
+ "#{new_issue_description(test)}#{RESULTS_SECTION_TEMPLATE}"
84
+ end
85
+
86
+ def issue_iid_from_testcase(testcase)
87
+ results = testcase.description.partition(RESULTS_SECTION_TEMPLATE).last if testcase.description.include?(RESULTS_SECTION_TEMPLATE)
88
+
89
+ return puts "No issue link found" unless results
90
+
91
+ issue_iid = results.split('/').last
92
+
93
+ issue_iid&.to_i
94
+ end
95
+
96
+ def find_or_create_issue(test)
97
+ issue = find_issue(test, 'issue')
31
98
 
32
99
  if issue
33
100
  puts "Found existing issue: #{issue.web_url}"
34
101
  else
35
- # Don't create new issues for skipped tests
36
- return if test.skipped
37
-
38
102
  issue = create_issue(test)
39
103
  puts "Created new issue: #{issue.web_url}"
40
104
  end
41
105
 
42
- test.testcase ||= issue.web_url
106
+ issue
107
+ end
43
108
 
44
- labels_updated = update_labels(issue, test)
45
- note_posted = note_status(issue, test)
109
+ def find_issue_by_iid(testcase, test)
110
+ iid = issue_iid_from_testcase(testcase)
46
111
 
47
- if labels_updated || note_posted
48
- puts "Issue updated."
49
- else
50
- puts "Test passed, no update needed."
51
- end
112
+ return unless iid
113
+
114
+ issues = search_issues(test: test, issue_type: 'issue', iid: iid)
115
+
116
+ warn(%(Issue iid "#{iid}" not valid)) if issues.empty?
117
+
118
+ issues.first
52
119
  end
53
120
 
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
121
+ def find_issue(test, issue_type)
122
+ issues = search_issues(test: test, issue_type: 'issue')
62
123
 
63
124
  warn(%(Too many issues found with the file path "#{test.file}" and name "#{test.name}")) if issues.many?
64
125
 
65
126
  issues.first
66
127
  end
67
128
 
129
+ def add_issue_to_testcase(testcase, issue)
130
+ results_section = testcase.description.include?(RESULTS_SECTION_TEMPLATE) ? '' : RESULTS_SECTION_TEMPLATE
131
+
132
+ gitlab.edit_issue(iid: testcase.iid, options: { description: (testcase.description + results_section + "\n\n#{issue.web_url}") })
133
+ end
134
+
135
+ def update_issue(issue, test)
136
+ new_labels = issue_labels(issue)
137
+ new_labels |= ['Testcase Linked']
138
+
139
+ labels_updated = update_labels(issue, test, new_labels)
140
+ note_posted = note_status(issue, test)
141
+
142
+ if labels_updated || note_posted
143
+ puts "Issue updated."
144
+ else
145
+ puts "Test passed, no update needed."
146
+ end
147
+ end
148
+
68
149
  def new_issue_labels(test)
69
- %w[status::automated]
150
+ ['Quality', "devops::#{test.stage}", 'status::automated']
70
151
  end
71
152
 
72
- def up_to_date_labels(test:, issue: nil)
153
+ def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
73
154
  labels = super
155
+ labels |= new_issue_labels(test).to_set
74
156
  labels.delete_if { |label| label.start_with?("#{pipeline}::") }
75
157
  labels << (test.failures.empty? ? "#{pipeline}::passed" : "#{pipeline}::failed")
76
158
  end
77
159
 
78
- def iid_from_testcase_url(url)
79
- url && url.split('/').last.to_i
160
+ def search_issues(test:, issue_type:, iid: nil)
161
+ gitlab.find_issues(iid: iid, options: { search: search_term(test) }) do |issue|
162
+ issue.state == 'opened' && issue.issue_type == issue_type && issue.title.strip == title_from_test(test)
163
+ end
80
164
  end
81
165
 
82
166
  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])
@@ -16,6 +16,26 @@ module Gitlab
16
16
  'QA_REMOTE_GRID_ACCESS_KEY' => :remote_grid_access_key,
17
17
  'QA_REMOTE_GRID_PROTOCOL' => :remote_grid_protocol,
18
18
  'QA_BROWSER' => :browser,
19
+ 'QA_ADDITIONAL_REPOSITORY_STORAGE' => :qa_additional_repository_storage,
20
+ 'QA_PRAEFECT_REPOSITORY_STORAGE' => :qa_praefect_repository_storage,
21
+ 'QA_GITALY_NON_CLUSTER_STORAGE' => :qa_gitaly_non_cluster_storage,
22
+ 'QA_COOKIES' => :qa_cookie,
23
+ 'QA_DEBUG' => :qa_debug,
24
+ 'QA_DEFAULT_BRANCH' => :qa_default_branch,
25
+ 'QA_LOG_PATH' => :qa_log_path,
26
+ 'QA_CAN_TEST_ADMIN_FEATURES' => :qa_can_test_admin_features,
27
+ 'QA_CAN_TEST_GIT_PROTOCOL_V2' => :qa_can_test_git_protocol_v2,
28
+ 'QA_CAN_TEST_PRAEFECT' => :qa_can_test_praefect,
29
+ 'QA_DISABLE_RSPEC_RETRY' => :qa_disable_rspec_retry,
30
+ 'QA_SIMULATE_SLOW_CONNECTION' => :qa_simulate_slow_connection,
31
+ 'QA_SLOW_CONNECTION_LATENCY_MS' => :qa_slow_connection_latency_ms,
32
+ 'QA_SLOW_CONNECTION_THROUGHPUT_KBPS' => :qa_slow_connection_throughput_kbps,
33
+ 'QA_GENERATE_ALLURE_REPORT' => :generate_allure_report,
34
+ 'QA_EXPORT_TEST_METRICS' => :qa_export_test_metrics,
35
+ 'QA_INFLUXDB_URL' => :qa_influxdb_url,
36
+ 'QA_INFLUXDB_TOKEN' => :qa_influxdb_token,
37
+ 'QA_RUN_TYPE' => :qa_run_type,
38
+ 'QA_SKIP_PULL' => :qa_skip_pull,
19
39
  'GITLAB_API_BASE' => :api_base,
20
40
  'GITLAB_ADMIN_USERNAME' => :admin_username,
21
41
  'GITLAB_ADMIN_PASSWORD' => :admin_password,
@@ -40,21 +60,6 @@ module Gitlab
40
60
  'CLOUDSDK_CORE_PROJECT' => :cloudsdk_core_project,
41
61
  'GCLOUD_REGION' => :gcloud_region,
42
62
  'SIGNUP_DISABLED' => :signup_disabled,
43
- 'QA_ADDITIONAL_REPOSITORY_STORAGE' => :qa_additional_repository_storage,
44
- 'QA_PRAEFECT_REPOSITORY_STORAGE' => :qa_praefect_repository_storage,
45
- 'QA_GITALY_NON_CLUSTER_STORAGE' => :qa_gitaly_non_cluster_storage,
46
- 'QA_COOKIES' => :qa_cookie,
47
- 'QA_DEBUG' => :qa_debug,
48
- 'QA_DEFAULT_BRANCH' => :qa_default_branch,
49
- 'QA_LOG_PATH' => :qa_log_path,
50
- 'QA_CAN_TEST_ADMIN_FEATURES' => :qa_can_test_admin_features,
51
- 'QA_CAN_TEST_GIT_PROTOCOL_V2' => :qa_can_test_git_protocol_v2,
52
- 'QA_CAN_TEST_PRAEFECT' => :qa_can_test_praefect,
53
- 'QA_DISABLE_RSPEC_RETRY' => :qa_disable_rspec_retry,
54
- 'QA_SIMULATE_SLOW_CONNECTION' => :qa_simulate_slow_connection,
55
- 'QA_SLOW_CONNECTION_LATENCY_MS' => :qa_slow_connection_latency_ms,
56
- 'QA_SLOW_CONNECTION_THROUGHPUT_KBPS' => :qa_slow_connection_throughput_kbps,
57
- 'QA_GENERATE_ALLURE_REPORT' => :generate_allure_report,
58
63
  'GITLAB_QA_USERNAME_1' => :gitlab_qa_username_1,
59
64
  'GITLAB_QA_PASSWORD_1' => :gitlab_qa_password_1,
60
65
  'GITLAB_QA_USERNAME_2' => :gitlab_qa_username_2,
@@ -74,13 +79,14 @@ module Gitlab
74
79
  'CI_NODE_INDEX' => :ci_node_index,
75
80
  'CI_NODE_TOTAL' => :ci_node_total,
76
81
  'CI_PROJECT_NAME' => :ci_project_name,
82
+ 'CI_SLACK_WEBHOOK_URL' => :ci_slack_webhook_url,
83
+ 'CI_PIPELINE_CREATED_AT' => :ci_pipeline_created_at,
84
+ 'CI_MERGE_REQUEST_IID' => :ci_merge_request_iid,
77
85
  'GITLAB_CI' => :gitlab_ci,
78
- 'QA_SKIP_PULL' => :qa_skip_pull,
79
86
  'ELASTIC_URL' => :elastic_url,
80
87
  'GITLAB_QA_LOOP_RUNNER_MINUTES' => :gitlab_qa_loop_runner_minutes,
81
88
  'MAILHOG_HOSTNAME' => :mailhog_hostname,
82
89
  'SLACK_QA_CHANNEL' => :slack_qa_channel,
83
- 'CI_SLACK_WEBHOOK_URL' => :ci_slack_webhook_url,
84
90
  'SLACK_ICON_EMOJI' => :slack_icon_emoji,
85
91
  'GITLAB_QA_FORMLESS_LOGIN_TOKEN' => :gitlab_qa_formless_login_token,
86
92
  'GEO_MAX_FILE_REPLICATION_TIME' => :geo_max_file_replication_time,
@@ -97,7 +103,8 @@ module Gitlab
97
103
  'AWS_S3_REGION' => :aws_s3_region,
98
104
  'AWS_S3_KEY_ID' => :aws_s3_key_id,
99
105
  'AWS_S3_ACCESS_KEY' => :aws_s3_access_key,
100
- 'AWS_S3_BUCKET_NAME' => :aws_s3_bucket_name
106
+ 'AWS_S3_BUCKET_NAME' => :aws_s3_bucket_name,
107
+ 'TOP_UPSTREAM_MERGE_REQUEST_IID' => :top_upstream_merge_request_iid
101
108
  }.freeze
102
109
 
103
110
  ENV_VARIABLES.each do |env_name, method_name|
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module QA
3
- VERSION = '7.7.3'.freeze
3
+ VERSION = '7.8.3'.freeze
4
4
  end
5
5
  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: 7.7.3
4
+ version: 7.8.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: 2021-08-31 00:00:00.000000000 Z
11
+ date: 2021-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control