dri 0.10.2 → 0.11.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/.gitlab-ci.yml +2 -2
- data/.rubocop.yml +9 -1
- data/.ruby-version +1 -1
- data/.tool-versions +1 -1
- data/Gemfile.lock +39 -32
- data/README.md +2 -17
- data/dri.gemspec +5 -4
- data/faq.yaml +7 -7
- data/lib/dri/api_client.rb +48 -2
- data/lib/dri/cli.rb +6 -0
- data/lib/dri/command.rb +4 -1
- data/lib/dri/commands/add/fast_quarantine.rb +74 -0
- data/lib/dri/commands/add.rb +46 -0
- data/lib/dri/commands/analyze/stack_traces.rb +1 -1
- data/lib/dri/commands/faq.rb +1 -1
- data/lib/dri/commands/fetch/failures.rb +82 -23
- data/lib/dri/commands/fetch/featureflags.rb +1 -1
- data/lib/dri/commands/fetch/pipelines.rb +3 -3
- data/lib/dri/commands/fetch/runbooks.rb +1 -1
- data/lib/dri/commands/fetch/testcases.rb +1 -1
- data/lib/dri/commands/fetch/triaged.rb +1 -1
- data/lib/dri/commands/fetch.rb +0 -24
- data/lib/dri/commands/incidents.rb +1 -1
- data/lib/dri/commands/init.rb +1 -1
- data/lib/dri/commands/profile.rb +3 -3
- data/lib/dri/commands/publish/report.rb +2 -4
- data/lib/dri/commands/rm/emoji.rb +1 -1
- data/lib/dri/commands/rm/profile.rb +1 -1
- data/lib/dri/commands/rm/reports.rb +1 -1
- data/lib/dri/commands/view/fast_quarantine.rb +27 -0
- data/lib/dri/commands/view.rb +23 -0
- data/lib/dri/feature_flag_report.rb +1 -1
- data/lib/dri/report.rb +12 -52
- data/lib/dri/support/influxdb_tools.rb +37 -0
- data/lib/dri/utils/constants.rb +2 -1
- data/lib/dri/version.rb +1 -1
- metadata +26 -8
- data/lib/dri/commands/fetch/quarantines.rb +0 -55
@@ -1,38 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "influxdb-client"
|
4
|
+
|
3
5
|
require_relative '../../command'
|
4
6
|
require_relative '../../utils/table'
|
5
7
|
require_relative '../../utils/constants'
|
8
|
+
require_relative '../../support/influxdb_tools'
|
6
9
|
|
7
10
|
module Dri
|
8
11
|
module Commands
|
9
12
|
class Fetch
|
10
|
-
class Failures < Dri::Command
|
13
|
+
class Failures < Dri::Command # rubocop:disable Metrics/ClassLength
|
11
14
|
include Dri::Utils::Table
|
12
15
|
include Dri::Utils::Constants::Triage::Labels
|
16
|
+
include Dri::Support::InfluxdbTools
|
13
17
|
using Refinements
|
14
18
|
|
15
19
|
def initialize(options)
|
16
20
|
@options = options
|
17
|
-
@start_date = @options[:start_date] ? Date.parse(@options[:start_date]) : Date.today
|
21
|
+
@start_date = @options[:start_date] ? Date.parse(@options[:start_date]) : Date.today - 1
|
18
22
|
@end_date = @options[:end_date] ? Date.parse(@options[:end_date]) : Date.today
|
19
23
|
@cutoff_time = @options[:cutoff] ? Time.parse(options[:cutoff]).utc : nil
|
20
24
|
end
|
21
25
|
|
22
|
-
def execute(
|
26
|
+
def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
23
27
|
verify_config_exists
|
24
28
|
|
25
|
-
urgent_environments = %w[canary canary.staging]
|
26
|
-
|
27
29
|
title = add_color('Title', :bright_yellow)
|
28
30
|
triaged = add_color('Triaged?', :bright_yellow)
|
29
31
|
environment = add_color('Environment', :bright_yellow)
|
30
|
-
author = add_color('Author', :bright_yellow)
|
31
32
|
url = add_color('URL', :bright_yellow)
|
32
33
|
updated_at = add_color('Updated at', :bright_yellow)
|
33
34
|
|
34
35
|
sorted_failures = []
|
35
|
-
labels = { title: title, triaged: triaged, environment: environment,
|
36
|
+
labels = { title: title, triaged: triaged, environment: environment, url: url,
|
36
37
|
updated_at: updated_at }
|
37
38
|
triaged_counter = 0
|
38
39
|
|
@@ -57,10 +58,30 @@ module Dri
|
|
57
58
|
exit 0
|
58
59
|
end
|
59
60
|
|
61
|
+
blocker_set = Set.new
|
62
|
+
|
63
|
+
blocker_set = Set.new
|
64
|
+
|
65
|
+
if query_api
|
66
|
+
begin
|
67
|
+
blockers = query_api.query(query: query_reliables_smokes)
|
68
|
+
|
69
|
+
blockers.each do |table|
|
70
|
+
table.records.each do |record|
|
71
|
+
blocker_set.add(record.values['name'])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
rescue StandardError => e
|
75
|
+
logger.error "An error occurred querying for reliable and smoke failures: #{e.message}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
60
79
|
failures.each do |failure|
|
61
80
|
project_id = failure.project_id
|
62
81
|
title = failure.title.truncate(60)
|
63
|
-
|
82
|
+
|
83
|
+
title = bold("*#{failure.title.truncate(60)}*") if blocker?(failure.title, blocker_set)
|
84
|
+
|
64
85
|
url = failure.web_url
|
65
86
|
updated_at = failure.updated_at
|
66
87
|
triaged = add_color('x', :red)
|
@@ -69,9 +90,6 @@ module Dri
|
|
69
90
|
|
70
91
|
env == 'gitlab.com' ? 'production' : env
|
71
92
|
end
|
72
|
-
urgent = urgent_environments.all? { |env| envs.include?(env) }
|
73
|
-
|
74
|
-
next if @options[:urgent] && !urgent
|
75
93
|
|
76
94
|
emoji_awards = api_client.fetch_awarded_emojis(failure.iid, project_id: project_id).find do |e|
|
77
95
|
e.name == emoji && e.to_h.dig('user', 'username') == username
|
@@ -82,33 +100,74 @@ module Dri
|
|
82
100
|
triaged_counter += 1
|
83
101
|
end
|
84
102
|
|
85
|
-
sorted_failures << { title: title, triaged: triaged, environment: envs.first || 'none',
|
103
|
+
sorted_failures << { title: title, triaged: triaged, environment: envs.first || 'none',
|
86
104
|
url: url, updated_at: updated_at }
|
87
105
|
end
|
88
106
|
|
89
107
|
sorted_failures.sort_by! { |failure| failure[@options[:sort_by]&.to_sym || :environment] }
|
90
108
|
end
|
91
109
|
|
92
|
-
msg =
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
else
|
97
|
-
<<~MSG
|
98
|
-
Found: #{sorted_failures.size} failures, of these #{triaged_counter} have been triaged with a #{emoji}.
|
99
|
-
MSG
|
100
|
-
end
|
110
|
+
msg = <<~MSG
|
111
|
+
Found: #{sorted_failures.size} failures, of these #{triaged_counter} have been triaged with a #{emoji}.
|
112
|
+
Smoke and Reliable failures are marked with *Failure..* in bold.
|
113
|
+
MSG
|
101
114
|
|
102
115
|
terminal_width = TTY::Screen.width
|
103
116
|
|
104
|
-
if terminal_width <= 210
|
117
|
+
if terminal_width <= 210
|
105
118
|
labels.delete(:updated_at)
|
106
119
|
sorted_failures.map { |failure| failure.delete(:updated_at) }
|
107
120
|
end
|
108
121
|
|
109
|
-
print_table(
|
122
|
+
print_table(
|
123
|
+
labels.values,
|
124
|
+
sorted_failures.map(&:values),
|
125
|
+
alignments: [:left, :center, :center, :left]
|
126
|
+
)
|
110
127
|
output.puts(msg)
|
111
128
|
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def blocker?(title, set)
|
133
|
+
title_part = title.split('|').last
|
134
|
+
return true if title_part&.strip && set.include?(title_part.strip)
|
135
|
+
|
136
|
+
false
|
137
|
+
end
|
138
|
+
|
139
|
+
def query_reliables_smokes
|
140
|
+
<<~QUERY
|
141
|
+
from(bucket: "#{Support::InfluxdbTools::INFLUX_MAIN_TEST_METRICS_BUCKET}")
|
142
|
+
|> range(start: -1d)
|
143
|
+
|> filter(fn: (r) => r._measurement == "test-stats")
|
144
|
+
|> filter(fn: (r) => r.run_type == "staging-full" or
|
145
|
+
r.run_type == "staging-sanity" or
|
146
|
+
r.run_type == "production-full" or
|
147
|
+
r.run_type == "production-sanity" or
|
148
|
+
r.run_type == "package-and-qa" or
|
149
|
+
r.run_type == "nightly" or
|
150
|
+
r.run_type == "e2e-test-on-gdk"
|
151
|
+
)
|
152
|
+
|> filter(fn: (r) => r.job_name != "airgapped" and
|
153
|
+
r.job_name != "instance-image-slow-network" and
|
154
|
+
r.job_name != "nplus1-instance-image"
|
155
|
+
)
|
156
|
+
|> filter(fn: (r) => r.status != "pending" and
|
157
|
+
r.merge_request == "false" and
|
158
|
+
r.quarantined == "false" and
|
159
|
+
r.smoke == "true" or
|
160
|
+
r.reliable == "true"
|
161
|
+
)
|
162
|
+
|> filter(fn: (r) => r["_field"] == "job_url" or
|
163
|
+
r["_field"] == "failure_exception" or
|
164
|
+
r["_field"] == "id"
|
165
|
+
)
|
166
|
+
|> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
|
167
|
+
|> group(columns: ["name"])
|
168
|
+
|> distinct(column: "name")
|
169
|
+
QUERY
|
170
|
+
end
|
112
171
|
end
|
113
172
|
end
|
114
173
|
end
|
@@ -17,7 +17,7 @@ module Dri
|
|
17
17
|
@today_iso_format = Time.now.strftime('%Y-%m-%dT00:00:00Z')
|
18
18
|
end
|
19
19
|
|
20
|
-
def execute(
|
20
|
+
def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
21
21
|
verify_config_exists
|
22
22
|
|
23
23
|
summary = add_color('Summary', :bright_yellow)
|
@@ -20,7 +20,7 @@ module Dri
|
|
20
20
|
@options = options
|
21
21
|
end
|
22
22
|
|
23
|
-
def execute(
|
23
|
+
def execute(*)
|
24
24
|
verify_config_exists
|
25
25
|
logger.info "Fetching pipelines' status, this might take a while..."
|
26
26
|
logger.warn "This command needs a large window to correctly print the table"
|
@@ -149,8 +149,8 @@ module Dri
|
|
149
149
|
# @param [Integer] pipeline_id
|
150
150
|
# @param [Boolean] sanity
|
151
151
|
def allure_report(pipeline_name:, pipeline_id:, sanity:)
|
152
|
-
"https://storage.googleapis.com/gitlab-qa-allure-reports/#{allure_bucket_name(pipeline_name, sanity)}"\
|
153
|
-
|
152
|
+
"https://storage.googleapis.com/gitlab-qa-allure-reports/#{allure_bucket_name(pipeline_name, sanity)}" \
|
153
|
+
"/master/#{pipeline_id}/index.html"
|
154
154
|
end
|
155
155
|
|
156
156
|
# Returns the GCP bucket name for different pipeline types
|
@@ -14,7 +14,7 @@ module Dri
|
|
14
14
|
@options = options
|
15
15
|
end
|
16
16
|
|
17
|
-
def execute(folder: nil,
|
17
|
+
def execute(folder: nil, _input: $stdin, output: $stdout)
|
18
18
|
return fetch_summary(output: output) unless folder
|
19
19
|
|
20
20
|
fetch_runbook("#{folder}/index.md", output: output)
|
data/lib/dri/commands/fetch.rb
CHANGED
@@ -48,8 +48,6 @@ module Dri
|
|
48
48
|
desc 'failures', 'Display failures opened on a given period.'
|
49
49
|
method_option :help, aliases: '-h', type: :boolean,
|
50
50
|
desc: 'Display usage information'
|
51
|
-
method_option :urgent, type: :boolean,
|
52
|
-
desc: 'Shows failures that quickly escalated'
|
53
51
|
method_option :sort_by, type: :string,
|
54
52
|
desc: 'Shows failures in specified order'
|
55
53
|
method_option :start_date, type: :string,
|
@@ -68,28 +66,6 @@ module Dri
|
|
68
66
|
end
|
69
67
|
end
|
70
68
|
|
71
|
-
desc 'quarantines', 'Display open quarantine MRs'
|
72
|
-
method_option :help, aliases: '-h', type: :boolean,
|
73
|
-
desc: 'Display usage information'
|
74
|
-
def quarantines(*)
|
75
|
-
if options[:help]
|
76
|
-
invoke :help, ['quarantines']
|
77
|
-
else
|
78
|
-
require_relative 'fetch/quarantines'
|
79
|
-
Dri::Commands::Fetch::Quarantines.new(options, search: '[QUARANTINE]').execute
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
desc 'dequarantines', 'Display open dequarantine MRs'
|
84
|
-
method_option :help, aliases: '-h', type: :boolean,
|
85
|
-
desc: 'Display usage information'
|
86
|
-
def dequarantines(*)
|
87
|
-
return invoke :help, %w[quarantines] if options[:help]
|
88
|
-
|
89
|
-
require_relative 'fetch/quarantines'
|
90
|
-
Dri::Commands::Fetch::Quarantines.new(options, search: '[DEQUARANTINE]').execute
|
91
|
-
end
|
92
|
-
|
93
69
|
desc 'pipelines', 'Display status of pipelines'
|
94
70
|
method_option :help, aliases: '-h', type: :boolean,
|
95
71
|
desc: 'Display pipelines usage information'
|
@@ -15,7 +15,7 @@ module Dri
|
|
15
15
|
@options = options
|
16
16
|
end
|
17
17
|
|
18
|
-
def execute(
|
18
|
+
def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
|
19
19
|
verify_config_exists
|
20
20
|
|
21
21
|
incident = add_color('Incident', :bright_yellow)
|
data/lib/dri/commands/init.rb
CHANGED
@@ -14,7 +14,7 @@ module Dri
|
|
14
14
|
puts pastel.yellow(font.write("DRI"))
|
15
15
|
end
|
16
16
|
|
17
|
-
def execute(
|
17
|
+
def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
|
18
18
|
output.puts "🤖 Welcome to DRI 🤖\n"
|
19
19
|
|
20
20
|
logger.info "🔎 Scanning for existing configurations...\n"
|
data/lib/dri/commands/profile.rb
CHANGED
@@ -11,7 +11,7 @@ module Dri
|
|
11
11
|
@options = options
|
12
12
|
end
|
13
13
|
|
14
|
-
def execute(
|
14
|
+
def execute(_input: $stdin, output: $stdout)
|
15
15
|
if config.exist? && @options["edit"]
|
16
16
|
editor.open(config.source_file)
|
17
17
|
return
|
@@ -39,13 +39,13 @@ module Dri
|
|
39
39
|
|
40
40
|
def pretty_print_profile
|
41
41
|
<<~PROFILE
|
42
|
-
#{add_color('User:', :bright_cyan)} #{username}
|
42
|
+
#{add_color('User:', :bright_cyan)} #{username}#{' '}
|
43
43
|
#{add_color('Token:', :bright_cyan)} #{token}
|
44
44
|
#{add_color('OpsToken:', :bright_cyan)} #{ops_token}
|
45
45
|
#{add_color('Timezone:', :bright_cyan)} #{timezone}
|
46
46
|
#{add_color('Emoji:', :bright_cyan)} #{emoji}
|
47
47
|
#{add_color('Report Path:', :bright_cyan)} #{handover_report_path}
|
48
|
-
|
48
|
+
|
49
49
|
PROFILE
|
50
50
|
end
|
51
51
|
end
|
@@ -24,7 +24,7 @@ module Dri
|
|
24
24
|
@today_iso_format = Time.now.strftime('%Y-%m-%dT00:00:00Z')
|
25
25
|
end
|
26
26
|
|
27
|
-
def execute(
|
27
|
+
def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
28
28
|
verify_config_exists
|
29
29
|
report = Dri::Report.new(config)
|
30
30
|
|
@@ -195,9 +195,7 @@ module Dri
|
|
195
195
|
FileUtils.mkdir_p("#{Dir.pwd}/handover_reports/.tmp")
|
196
196
|
report_path = "handover_reports/.tmp/report-#{@date}.json"
|
197
197
|
|
198
|
-
File.
|
199
|
-
out_file.write(posted_note.to_h.to_json)
|
200
|
-
end
|
198
|
+
File.write(report_path, posted_note.to_h.to_json)
|
201
199
|
end
|
202
200
|
|
203
201
|
output.puts "Done! ✅\n"
|
@@ -10,7 +10,7 @@ module Dri
|
|
10
10
|
@options = options
|
11
11
|
end
|
12
12
|
|
13
|
-
def execute(
|
13
|
+
def execute(_input: $stdin, output: $stdout) # rubocop:disable Metrics/AbcSize
|
14
14
|
verify_config_exists
|
15
15
|
|
16
16
|
remove = prompt.yes? "Are you sure you want to remove all #{emoji} award emojis from issues?"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../command'
|
4
|
+
|
5
|
+
module Dri
|
6
|
+
module Commands
|
7
|
+
class View
|
8
|
+
class FastQuarantine < Dri::Command
|
9
|
+
def initialize(options)
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute(*)
|
14
|
+
verify_config_exists
|
15
|
+
|
16
|
+
logger.info "Fetching fast quarantined tests..."
|
17
|
+
|
18
|
+
file_content = api_client.get_fast_quarantine_tests
|
19
|
+
|
20
|
+
file_content.each_line do |line|
|
21
|
+
puts "• #{line}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Dri
|
6
|
+
module Commands
|
7
|
+
class View < Thor
|
8
|
+
namespace :view
|
9
|
+
|
10
|
+
desc 'fastquarantine', 'View fast-quarantine tests'
|
11
|
+
method_option :help, aliases: '-h', type: :boolean,
|
12
|
+
desc: 'Display usage information'
|
13
|
+
def fastquarantine(*)
|
14
|
+
if options[:help]
|
15
|
+
invoke :help, ['fastquarantine']
|
16
|
+
else
|
17
|
+
require_relative 'view/fast_quarantine'
|
18
|
+
Dri::Commands::View::FastQuarantine.new(options).execute
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -26,7 +26,7 @@ module Dri
|
|
26
26
|
feature_flag_data = [summary, changed_on, url]
|
27
27
|
|
28
28
|
labels = feature_flag.labels
|
29
|
-
host_label = labels.select { |label| /^host::/.match(label) }.join
|
29
|
+
host_label = labels.select { |label| /^host::/.match(label) }.join
|
30
30
|
|
31
31
|
case host_label
|
32
32
|
when PRODUCTION
|
data/lib/dri/report.rb
CHANGED
@@ -63,66 +63,17 @@ module Dri
|
|
63
63
|
|
64
64
|
failure_type = filter_failure_type_labels(labels)
|
65
65
|
assigned_status = assigned?(failure["assignees"])
|
66
|
-
pipelines =
|
67
|
-
|
68
|
-
linked_pipelines = link_pipelines(project_id, iid, pipelines, description)
|
66
|
+
pipelines = format_pipelines(labels)
|
69
67
|
|
70
68
|
actions_status = actions_status_template(failure_type, assigned_status, actions_opts)
|
71
69
|
actions_fixes = actions_fixes_template(related_mrs)
|
72
70
|
|
73
|
-
@failures << [title, emojified_link,
|
71
|
+
@failures << [title, emojified_link, pipelines, stack_trace, "#{actions_status}#{actions_fixes}"]
|
74
72
|
end
|
75
73
|
|
76
74
|
private
|
77
75
|
|
78
|
-
def
|
79
|
-
linked = []
|
80
|
-
label_pipeline_map = {
|
81
|
-
'gitlab.com' => '/quality/production',
|
82
|
-
'canary.gitlab.com' => '/quality/canary',
|
83
|
-
'canary.staging.gitlab.com' => '/quality/staging-canary',
|
84
|
-
'main' => '/gitlab-org/gitlab-qa-mirror',
|
85
|
-
'master' => '/gitlab-org/gitlab-qa-mirror',
|
86
|
-
'pre.gitlab.com' => '/quality/preprod',
|
87
|
-
'staging-ref' => '/quality/staging-ref',
|
88
|
-
'staging.gitlab.com' => '/quality/staging',
|
89
|
-
'release' => '/quality/release'
|
90
|
-
}
|
91
|
-
|
92
|
-
failure_notes = @api_client.fetch_failure_notes(project_id, iid)
|
93
|
-
|
94
|
-
return if pipelines.empty?
|
95
|
-
|
96
|
-
pipelines.each do |pipeline|
|
97
|
-
next unless label_pipeline_map.has_key?(pipeline)
|
98
|
-
|
99
|
-
pipeline_in_notes_found = false
|
100
|
-
pipeline_link = ''
|
101
|
-
pipeline_markdown = pipeline.gsub(/.gitlab.com/, '')
|
102
|
-
|
103
|
-
failure_notes.each do |note|
|
104
|
-
next unless note.body.include?(label_pipeline_map.fetch(pipeline))
|
105
|
-
|
106
|
-
pipeline_in_notes_found = true
|
107
|
-
pipeline_link = URI.extract(note.body, %w[https])
|
108
|
-
end
|
109
|
-
|
110
|
-
unless pipeline_in_notes_found
|
111
|
-
links_description = URI.extract(description, %w[https])
|
112
|
-
pipeline_link = links_description.select { |link| link.include? label_pipeline_map.fetch(pipeline) }
|
113
|
-
end
|
114
|
-
|
115
|
-
unless pipeline_link.empty?
|
116
|
-
pipeline_link_sanitized = pipeline_link.join.strip
|
117
|
-
pipeline_markdown = "[#{pipeline_markdown}](#{pipeline_link_sanitized})"
|
118
|
-
end
|
119
|
-
|
120
|
-
linked << pipeline_markdown
|
121
|
-
end
|
122
|
-
linked.join(', ')
|
123
|
-
end
|
124
|
-
|
125
|
-
def actions_status_template(failure_type, assigned_status, actions_opts) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity/MethodLength
|
76
|
+
def actions_status_template(failure_type, assigned_status, actions_opts) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity/
|
126
77
|
quarantined = ''
|
127
78
|
reproduced = ''
|
128
79
|
transient = ''
|
@@ -184,6 +135,15 @@ module Dri
|
|
184
135
|
pipelines
|
185
136
|
end
|
186
137
|
|
138
|
+
def format_pipelines(labels)
|
139
|
+
labels.filter_map do |label|
|
140
|
+
next unless label.include?(FOUND)
|
141
|
+
|
142
|
+
sanitized_label = label.gsub(FOUND, ' ').strip
|
143
|
+
sanitized_label.gsub(/.gitlab.com/, '')
|
144
|
+
end.join(', ')
|
145
|
+
end
|
146
|
+
|
187
147
|
def filter_failure_type_labels(labels)
|
188
148
|
labels.each do |label|
|
189
149
|
@type = label.gsub!(FAILURE, ' ').to_s if label.include? FAILURE
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dri
|
4
|
+
module Support
|
5
|
+
# Common tools for use with influxdb metrics setup
|
6
|
+
#
|
7
|
+
module InfluxdbTools
|
8
|
+
# @return [String] bucket for storing metrics from main runs
|
9
|
+
INFLUX_MAIN_TEST_METRICS_BUCKET = "e2e-test-stats-main"
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Query client
|
14
|
+
#
|
15
|
+
# @return [QueryApi]
|
16
|
+
def query_api
|
17
|
+
return nil unless influx_client
|
18
|
+
|
19
|
+
@query_api ||= influx_client.create_query_api
|
20
|
+
end
|
21
|
+
|
22
|
+
# InfluxDb client
|
23
|
+
#
|
24
|
+
# @return [InfluxDB2::Client]
|
25
|
+
def influx_client
|
26
|
+
return nil unless ENV["QA_INFLUXDB_URL"] && ENV["QA_INFLUXDB_TOKEN"]
|
27
|
+
|
28
|
+
@influx_client ||= InfluxDB2::Client.new(
|
29
|
+
ENV.fetch("QA_INFLUXDB_URL", nil),
|
30
|
+
ENV.fetch("QA_INFLUXDB_TOKEN", nil),
|
31
|
+
bucket: INFLUX_MAIN_TEST_METRICS_BUCKET,
|
32
|
+
org: "gitlab-qa"
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/dri/utils/constants.rb
CHANGED
@@ -11,13 +11,14 @@ module Dri
|
|
11
11
|
FEATURE_FLAG_LOG_PROJECT_ID = 15208716
|
12
12
|
INFRA_TEAM_PROD_PROJECT_ID = 7444821
|
13
13
|
RUNBOOKS_PROJECT_ID = 41045213
|
14
|
+
FAST_QUARANTINE_PROJECT_ID = 45427186
|
14
15
|
end
|
15
16
|
|
16
17
|
module Triage
|
17
18
|
module Labels
|
18
19
|
FOUND = 'found:'
|
19
20
|
FAILURE = 'failure::'
|
20
|
-
FAILURE_NEW = "#{FAILURE}new"
|
21
|
+
FAILURE_NEW = "#{FAILURE}new".freeze
|
21
22
|
QA = "QA"
|
22
23
|
INCIDENT = 'Incident::'
|
23
24
|
SERVICE = 'Service::'
|
data/lib/dri/version.rb
CHANGED