gitlab_quality-test_tooling 1.11.0 → 1.12.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +4 -2
- data/exe/flaky-test-issues +5 -0
- data/lib/gitlab_quality/test_tooling/concerns/find_set_dri.rb +47 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/branches_client.rb +18 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/branches_dry_client.rb +15 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/commits_client.rb +18 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/commits_dry_client.rb +14 -0
- data/lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_client.rb +14 -9
- data/lib/gitlab_quality/test_tooling/gitlab_client/repository_files_client.rb +23 -0
- data/lib/gitlab_quality/test_tooling/report/flaky_test_issue.rb +13 -3
- data/lib/gitlab_quality/test_tooling/report/relate_failure_issue.rb +2 -2
- data/lib/gitlab_quality/test_tooling/report/slow_test_issue.rb +1 -1
- data/lib/gitlab_quality/test_tooling/slack/post_to_slack_dry.rb +14 -0
- data/lib/gitlab_quality/test_tooling/version.rb +1 -1
- metadata +13 -7
- data/lib/gitlab_quality/test_tooling/report/concerns/find_set_dri.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b88e790bd74462ff96779cb28d8f8f2cdadd99356e3889f50ec56ed7f5ea691d
|
4
|
+
data.tar.gz: 865098baec02cb4f7cf6634fc7e7cb45a0394261957d9b0cdc33b9c0efd74c29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bdaa39d9a6e2ea9000d3318d54e1c3385c552fa967b86780f697ee10becf7e6f0cc3c8edf19a7ac7d29988babaf6ad735a1191d7132ed7f635939cde3575fa6
|
7
|
+
data.tar.gz: 3edfd0209db270145f48338dbf0ebc1785176f8fd158fef8880b13b3280e8a569437d30f26234203bb58bbb6b111992265209882df4c783b83342b942d2d7d00
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -144,12 +144,14 @@ Usage: exe/slow-test-issues [options]
|
|
144
144
|
### `exe/flaky-test-issues`
|
145
145
|
|
146
146
|
```shell
|
147
|
-
Purpose:
|
147
|
+
Purpose: Create flaky test issues for any passed test coming from rspec-retry JSON report files.
|
148
148
|
Usage: exe/flaky-test-issues [options]
|
149
149
|
-i, --input-files INPUT_FILES JSON rspec-retry report files
|
150
150
|
-p, --project PROJECT Can be an integer or a group/project string
|
151
151
|
-m MERGE_REQUEST_IID, An integer merge request IID
|
152
152
|
--merge_request_iid
|
153
|
+
--base-issue-labels BASE_ISSUE_LABELS
|
154
|
+
Comma-separated labels (without tilde) to add to new flaky test issues
|
153
155
|
-t, --token TOKEN A valid access token with `api` scope and Maintainer permission in PROJECT
|
154
156
|
--dry-run Perform a dry-run (don't create issues)
|
155
157
|
-v, --version Show the version
|
@@ -217,7 +219,7 @@ If you forget to set the changelog entry in your commit messages, you can also e
|
|
217
219
|
|
218
220
|
### Steps to release
|
219
221
|
|
220
|
-
Use a `Release` merge request template and create a merge
|
222
|
+
Use a `Release` merge request template and create a merge request to update the version number in `version.rb`, and get the merge request merged by a maintainer.
|
221
223
|
|
222
224
|
This will then be packaged into a gem and pushed to [rubygems.org](https://rubygems.org) by the CI/CD.
|
223
225
|
|
data/exe/flaky-test-issues
CHANGED
@@ -23,6 +23,11 @@ options = OptionParser.new do |opts|
|
|
23
23
|
params[:merge_request_iid] = merge_request_iid
|
24
24
|
end
|
25
25
|
|
26
|
+
opts.on('--base-issue-labels BASE_ISSUE_LABELS', String,
|
27
|
+
'Comma-separated labels (without tilde) to add to new flaky test issues') do |base_issue_labels|
|
28
|
+
params[:base_issue_labels] = base_issue_labels.split(',')
|
29
|
+
end
|
30
|
+
|
26
31
|
opts.on('-t', '--token TOKEN', String, 'A valid access token with `api` scope and Maintainer permission in PROJECT') do |token|
|
27
32
|
params[:token] = token
|
28
33
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module GitlabQuality
|
6
|
+
module TestTooling
|
7
|
+
module Concerns
|
8
|
+
module FindSetDri
|
9
|
+
def set_dri_via_group(product_group, stage)
|
10
|
+
parse_json_with_sets
|
11
|
+
fetch_stage_sets(stage)
|
12
|
+
|
13
|
+
return @sets.sample['username'] if @stage_sets.empty?
|
14
|
+
|
15
|
+
fetch_group_sets(product_group)
|
16
|
+
|
17
|
+
if @group_sets.empty?
|
18
|
+
@stage_sets.sample['username']
|
19
|
+
else
|
20
|
+
@group_sets.sample['username']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def parse_json_with_sets
|
27
|
+
response = Support::HttpRequest.make_http_request(
|
28
|
+
url: 'https://gitlab-org.gitlab.io/gitlab-roulette/roulette.json'
|
29
|
+
)
|
30
|
+
@sets = JSON.parse(response.body).select { |user| user['role'].include?('software-engineer-in-test') }
|
31
|
+
end
|
32
|
+
|
33
|
+
def fetch_stage_sets(stage)
|
34
|
+
@stage_sets = @sets.select do |user|
|
35
|
+
user['role'].include?(stage.split("_").map(&:capitalize).join(" "))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch_group_sets(product_group)
|
40
|
+
@group_sets = @stage_sets.select do |user|
|
41
|
+
user['role'].downcase.tr(' ', '_').include?(product_group)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitlabQuality
|
4
|
+
module TestTooling
|
5
|
+
module GitlabClient
|
6
|
+
class BranchesClient < GitlabClient
|
7
|
+
def create(branch_name, ref)
|
8
|
+
branch = handle_gitlab_client_exceptions do
|
9
|
+
client.create_branch(project, branch_name, ref)
|
10
|
+
end
|
11
|
+
|
12
|
+
Runtime::Logger.debug("Created branch #{branch['name']} (#{branch['web_url']})")
|
13
|
+
branch
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitlabQuality
|
4
|
+
module TestTooling
|
5
|
+
module GitlabClient
|
6
|
+
class BranchesDryClient < BranchesClient
|
7
|
+
def create(branch_name, ref)
|
8
|
+
branch = { 'name' => branch_name, 'web_url' => 'https://example.com/dummy/branch/url' }
|
9
|
+
puts "A branch would have been created with name: #{branch['name']}, web_url: #{branch['web_url']} and ref: #{ref}"
|
10
|
+
branch
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitlabQuality
|
4
|
+
module TestTooling
|
5
|
+
module GitlabClient
|
6
|
+
class CommitsClient < GitlabClient
|
7
|
+
def create(branch_name, file_path, new_content, message)
|
8
|
+
commit = client.create_commit(project, branch_name, message, [
|
9
|
+
{ action: :update, file_path: file_path, content: new_content }
|
10
|
+
])
|
11
|
+
|
12
|
+
Runtime::Logger.debug("Created commit #{commit['id']} (#{commit['web_url']}) on #{branch_name}")
|
13
|
+
commit
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitlabQuality
|
4
|
+
module TestTooling
|
5
|
+
module GitlabClient
|
6
|
+
class CommitsDryClient < CommitsClient
|
7
|
+
def create(branch_name, file_path, new_content, message)
|
8
|
+
puts "A commit would have been created on branch_name: #{branch_name}, file_path: #{file_path}, message: #{message} and content:"
|
9
|
+
puts new_content
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'gitlab'
|
4
|
-
|
5
3
|
module GitlabQuality
|
6
4
|
module TestTooling
|
7
5
|
module GitlabClient
|
@@ -10,19 +8,26 @@ module GitlabQuality
|
|
10
8
|
client.merge_request_changes(project, merge_request_iid)
|
11
9
|
end
|
12
10
|
|
13
|
-
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:)
|
11
|
+
def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id: nil)
|
12
|
+
attrs = {
|
13
|
+
source_branch: source_branch,
|
14
|
+
target_branch: target_branch,
|
15
|
+
description: description,
|
16
|
+
labels: labels,
|
17
|
+
assignee_id: assignee_id,
|
18
|
+
squash: true,
|
19
|
+
remove_source_branch: true
|
20
|
+
}.compact
|
21
|
+
|
14
22
|
merge_request = handle_gitlab_client_exceptions do
|
15
23
|
client.create_merge_request(project,
|
16
24
|
title,
|
17
|
-
|
18
|
-
target_branch: target_branch,
|
19
|
-
description: description,
|
20
|
-
labels: labels,
|
21
|
-
squash: true,
|
22
|
-
remove_source_branch: true)
|
25
|
+
attrs)
|
23
26
|
end
|
24
27
|
|
25
28
|
Runtime::Logger.debug("Created merge request #{merge_request['iid']} (#{merge_request['web_url']})") if merge_request
|
29
|
+
|
30
|
+
merge_request
|
26
31
|
end
|
27
32
|
|
28
33
|
def find(iid: nil, options: {}, &select)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitlabQuality
|
4
|
+
module TestTooling
|
5
|
+
module GitlabClient
|
6
|
+
class RepositoryFilesClient < GitlabClient
|
7
|
+
attr_reader :file_path
|
8
|
+
|
9
|
+
def initialize(file_path:, **kwargs)
|
10
|
+
@file_path = file_path
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def file_contents
|
16
|
+
handle_gitlab_client_exceptions do
|
17
|
+
client.file_contents(project, file_path.gsub(%r{^/}, ""))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -19,14 +19,24 @@ module GitlabQuality
|
|
19
19
|
FOUND_IN_MR_LABEL = 'found:in MR'
|
20
20
|
FOUND_IN_MASTER_LABEL = 'found:master'
|
21
21
|
|
22
|
-
def initialize(
|
22
|
+
def initialize(
|
23
|
+
token:,
|
24
|
+
input_files:,
|
25
|
+
base_issue_labels: nil,
|
26
|
+
confidential: false,
|
27
|
+
dry_run: false,
|
28
|
+
merge_request_iid: nil,
|
29
|
+
project: nil,
|
30
|
+
**_kwargs)
|
23
31
|
super(token: token, input_files: input_files, project: project, confidential: confidential, dry_run: dry_run)
|
32
|
+
|
33
|
+
@base_issue_labels = Set.new(base_issue_labels)
|
24
34
|
@merge_request_iid = merge_request_iid
|
25
35
|
end
|
26
36
|
|
27
37
|
private
|
28
38
|
|
29
|
-
attr_reader :merge_request_iid
|
39
|
+
attr_reader :base_issue_labels, :merge_request_iid
|
30
40
|
|
31
41
|
def run!
|
32
42
|
puts "Reporting flaky tests in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
|
@@ -54,7 +64,7 @@ module GitlabQuality
|
|
54
64
|
FOUND_IN_MR_LABEL
|
55
65
|
end
|
56
66
|
|
57
|
-
NEW_ISSUE_LABELS + [found_label]
|
67
|
+
NEW_ISSUE_LABELS + base_issue_labels + [found_label]
|
58
68
|
end
|
59
69
|
|
60
70
|
def new_issue_description(test)
|
@@ -16,7 +16,7 @@ module GitlabQuality
|
|
16
16
|
# - Find issue by title (with test description or test file), then further filter by stack trace, then pick the better-matching one
|
17
17
|
# - Add the failed job to the issue description, and update labels
|
18
18
|
class RelateFailureIssue < ReportAsIssue
|
19
|
-
include Concerns::FindSetDri
|
19
|
+
include TestTooling::Concerns::FindSetDri
|
20
20
|
include Concerns::GroupAndCategoryLabels
|
21
21
|
include Concerns::IssueReports
|
22
22
|
include Amatch
|
@@ -332,7 +332,7 @@ module GitlabQuality
|
|
332
332
|
def new_issue_assignee_id(test)
|
333
333
|
return unless test.product_group?
|
334
334
|
|
335
|
-
dri = set_dri_via_group(test.product_group, test)
|
335
|
+
dri = set_dri_via_group(test.product_group, test.stage)
|
336
336
|
puts " => Assigning #{dri} as DRI for the issue."
|
337
337
|
|
338
338
|
gitlab.find_user_id(username: dri)
|
@@ -10,7 +10,7 @@ module GitlabQuality
|
|
10
10
|
# - Find issue by title (with test description or test file)
|
11
11
|
# - Add test metadata, duration to the issue with group and category labels
|
12
12
|
class SlowTestIssue < ReportAsIssue
|
13
|
-
include Concerns::FindSetDri
|
13
|
+
include TestTooling::Concerns::FindSetDri
|
14
14
|
include Concerns::GroupAndCategoryLabels
|
15
15
|
|
16
16
|
NEW_ISSUE_LABELS = Set.new(['test', 'type::maintenance', 'maintenance::performance', 'priority::3', 'severity::3', 'rspec profiling', 'rspec:slow test']).freeze
|
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.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab Quality
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|
@@ -383,15 +383,20 @@ files:
|
|
383
383
|
- exe/update-screenshot-paths
|
384
384
|
- lefthook.yml
|
385
385
|
- lib/gitlab_quality/test_tooling.rb
|
386
|
+
- lib/gitlab_quality/test_tooling/concerns/find_set_dri.rb
|
386
387
|
- lib/gitlab_quality/test_tooling/failed_jobs_table.rb
|
388
|
+
- lib/gitlab_quality/test_tooling/gitlab_client/branches_client.rb
|
389
|
+
- lib/gitlab_quality/test_tooling/gitlab_client/branches_dry_client.rb
|
390
|
+
- lib/gitlab_quality/test_tooling/gitlab_client/commits_client.rb
|
391
|
+
- lib/gitlab_quality/test_tooling/gitlab_client/commits_dry_client.rb
|
387
392
|
- lib/gitlab_quality/test_tooling/gitlab_client/gitlab_client.rb
|
388
393
|
- lib/gitlab_quality/test_tooling/gitlab_client/issues_client.rb
|
389
394
|
- lib/gitlab_quality/test_tooling/gitlab_client/issues_dry_client.rb
|
390
395
|
- lib/gitlab_quality/test_tooling/gitlab_client/jobs_client.rb
|
391
396
|
- lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_client.rb
|
392
397
|
- lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_dry_client.rb
|
398
|
+
- lib/gitlab_quality/test_tooling/gitlab_client/repository_files_client.rb
|
393
399
|
- lib/gitlab_quality/test_tooling/labels_inference.rb
|
394
|
-
- lib/gitlab_quality/test_tooling/report/concerns/find_set_dri.rb
|
395
400
|
- lib/gitlab_quality/test_tooling/report/concerns/group_and_category_labels.rb
|
396
401
|
- lib/gitlab_quality/test_tooling/report/concerns/issue_reports.rb
|
397
402
|
- lib/gitlab_quality/test_tooling/report/concerns/results_reporter.rb
|
@@ -411,6 +416,7 @@ files:
|
|
411
416
|
- lib/gitlab_quality/test_tooling/runtime/env.rb
|
412
417
|
- lib/gitlab_quality/test_tooling/runtime/logger.rb
|
413
418
|
- lib/gitlab_quality/test_tooling/slack/post_to_slack.rb
|
419
|
+
- lib/gitlab_quality/test_tooling/slack/post_to_slack_dry.rb
|
414
420
|
- lib/gitlab_quality/test_tooling/summary_table.rb
|
415
421
|
- lib/gitlab_quality/test_tooling/support/http_request.rb
|
416
422
|
- lib/gitlab_quality/test_tooling/system_logs/finders/json_log_finder.rb
|
@@ -443,7 +449,7 @@ metadata:
|
|
443
449
|
homepage_uri: https://gitlab.com/gitlab-org/ruby/gems/gitlab_quality-test_tooling
|
444
450
|
source_code_uri: https://gitlab.com/gitlab-org/ruby/gems/gitlab_quality-test_tooling
|
445
451
|
changelog_uri: https://gitlab.com/gitlab-org/ruby/gems/gitlab_quality-test_tooling/-/releases
|
446
|
-
post_install_message:
|
452
|
+
post_install_message:
|
447
453
|
rdoc_options: []
|
448
454
|
require_paths:
|
449
455
|
- lib
|
@@ -458,8 +464,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
458
464
|
- !ruby/object:Gem::Version
|
459
465
|
version: '0'
|
460
466
|
requirements: []
|
461
|
-
rubygems_version: 3.
|
462
|
-
signing_key:
|
467
|
+
rubygems_version: 3.3.26
|
468
|
+
signing_key:
|
463
469
|
specification_version: 4
|
464
470
|
summary: A collection of test-related tools.
|
465
471
|
test_files: []
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
module GitlabQuality
|
6
|
-
module TestTooling
|
7
|
-
module Report
|
8
|
-
module Concerns
|
9
|
-
module FindSetDri
|
10
|
-
def set_dri_via_group(product_group, test)
|
11
|
-
parse_json_with_sets
|
12
|
-
fetch_stage_sets(test)
|
13
|
-
|
14
|
-
return @sets.sample['username'] if @stage_sets.empty?
|
15
|
-
|
16
|
-
fetch_group_sets(product_group)
|
17
|
-
|
18
|
-
if @group_sets.empty?
|
19
|
-
@stage_sets.sample['username']
|
20
|
-
else
|
21
|
-
@group_sets.sample['username']
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def parse_json_with_sets
|
28
|
-
response = Support::HttpRequest.make_http_request(
|
29
|
-
url: 'https://gitlab-org.gitlab.io/gitlab-roulette/roulette.json'
|
30
|
-
)
|
31
|
-
@sets = JSON.parse(response.body).select { |user| user['role'].include?('software-engineer-in-test') }
|
32
|
-
end
|
33
|
-
|
34
|
-
def fetch_stage_sets(test)
|
35
|
-
@stage_sets = @sets.select do |user|
|
36
|
-
user['role'].include?(test.stage.split("_").map(&:capitalize).join(" "))
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def fetch_group_sets(product_group)
|
41
|
-
@group_sets = @stage_sets.select do |user|
|
42
|
-
user['role'].downcase.tr(' ', '_').include?(product_group)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|