dri 0.10.2 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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