Skip to content

Commit 0e7e7c2

Browse files
committed
Test Additional metrics parser and fix query checking tests
1 parent f78fd3d commit 0e7e7c2

File tree

5 files changed

+265
-11
lines changed

5 files changed

+265
-11
lines changed

app/models/project_services/prometheus_service.rb

-4
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ def matched_metrics
7575
with_reactive_cache(Gitlab::Prometheus::Queries::MatchedMetricsQuery.name, &:itself)
7676
end
7777

78-
def with_reactive_cache(*args, &block)
79-
yield calculate_reactive_cache(*args)
80-
end
81-
8278
# Cache metrics for specific environment
8379
def calculate_reactive_cache(query_class_name, *args)
8480
return unless active? && project && !project.pending_delete?

lib/gitlab/prometheus/additional_metrics_parser.rb

+11-4
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,29 @@ def metrics_from_list(list)
1414
end
1515

1616
def metric_from_entry(entry)
17-
missing_fields = [:title, :required_metrics, :weight, :queries].select { |key| !entry.key?(key) }
17+
required_fields = [:title, :required_metrics, :weight, :queries]
18+
missing_fields = required_fields.select { |key| entry[key].nil? }
1819
raise ParsingError.new("entry missing required fields #{missing_fields}") unless missing_fields.empty?
1920

2021
Metric.new(entry[:title], entry[:required_metrics], entry[:weight], entry[:y_label], entry[:queries])
2122
end
2223

2324
def group_from_entry(entry)
24-
missing_fields = [:group, :priority, :metrics].select { |key| !entry.key?(key) }
25-
raise ParsingError.new("entry missing required fields #{missing_fields}") unless missing_fields.empty?
25+
required_fields = [:group, :priority, :metrics]
26+
missing_fields = required_fields.select { |key| entry[key].nil? }
27+
28+
raise ParsingError.new("entry missing required fields #{missing_fields.map(&:to_s)}") unless missing_fields.empty?
2629

2730
group = MetricGroup.new(entry[:group], entry[:priority])
2831
group.tap { |g| g.metrics = metrics_from_list(entry[:metrics]) }
2932
end
3033

3134
def additional_metrics_raw
32-
@additional_metrics_raw ||= YAML.load_file(Rails.root.join('config/additional_metrics.yml'))&.map(&:deep_symbolize_keys).freeze
35+
@additional_metrics_raw ||= load_yaml_file&.map(&:deep_symbolize_keys).freeze
36+
end
37+
38+
def load_yaml_file
39+
YAML.load_file(Rails.root.join('config/additional_metrics.yml'))
3340
end
3441
end
3542
end

lib/gitlab/prometheus/queries/query_additional_metrics.rb

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,19 @@ def group_with_any_metrics(group)
3737

3838
def query_with_result(query)
3939
query[:result]&.any? do |item|
40-
item&.[]('values')&.any? || item&.[]('value')&.any?
40+
item&.[](:values)&.any? || item&.[](:value)&.any?
4141
end
4242
end
4343

4444
def process_query(context, query)
4545
query_with_result = query.dup
46-
query_with_result[:result] =
46+
result =
4747
if query.key?(:query_range)
4848
client_query_range(query[:query_range] % context, start: context[:timeframe_start], stop: context[:timeframe_end])
4949
else
5050
client_query(query[:query] % context, time: context[:timeframe_end])
5151
end
52+
query_with_result[:result] = result&.map(&:deep_symbolize_keys)
5253
query_with_result
5354
end
5455

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
require 'spec_helper'
2+
3+
describe Gitlab::Prometheus::AdditionalMetricsParser, lib: true do
4+
include Prometheus::MetricBuilders
5+
6+
let(:parser_error_class) { Gitlab::Prometheus::ParsingError }
7+
8+
describe '#load_groups_from_yaml' do
9+
subject { described_class.load_groups_from_yaml }
10+
11+
describe 'parsing sample yaml' do
12+
let(:sample_yaml) do
13+
<<-EOF.strip_heredoc
14+
- group: group_a
15+
priority: 1
16+
metrics:
17+
- title: "title"
18+
required_metrics: [ metric_a, metric_b ]
19+
weight: 1
20+
queries: [{ query_range: 'query_range_a', label: label, unit: unit }]
21+
- title: "title"
22+
required_metrics: [metric_a]
23+
weight: 1
24+
queries: [{ query_range: 'query_range_empty' }]
25+
- group: group_b
26+
priority: 1
27+
metrics:
28+
- title: title
29+
required_metrics: []
30+
weight: 1
31+
queries: [{query_range: query_range_a}]
32+
EOF
33+
end
34+
35+
before do
36+
described_class.instance_variable_set :@additional_metrics_raw, nil
37+
allow(described_class).to receive(:load_yaml_file) { YAML.load(sample_yaml) }
38+
end
39+
40+
it 'parses to two metric groups with 2 and 1 metric respectively' do
41+
expect(subject.count).to eq(2)
42+
expect(subject[0].metrics.count).to eq(2)
43+
expect(subject[1].metrics.count).to eq(1)
44+
end
45+
46+
it 'provide group data' do
47+
expect(subject[0]).to have_attributes(name: 'group_a', priority: 1)
48+
expect(subject[1]).to have_attributes(name: 'group_b', priority: 1)
49+
end
50+
51+
it 'provides metrics data' do
52+
metrics = subject.flat_map(&:metrics)
53+
54+
expect(metrics.count).to eq(3)
55+
expect(metrics[0]).to have_attributes(title: 'title', required_metrics: %w(metric_a metric_b), weight: 1)
56+
expect(metrics[1]).to have_attributes(title: 'title', required_metrics: %w(metric_a), weight: 1)
57+
expect(metrics[2]).to have_attributes(title: 'title', required_metrics: [], weight: 1)
58+
end
59+
60+
it 'provides query data' do
61+
queries = subject.flat_map(&:metrics).flat_map(&:queries)
62+
63+
expect(queries.count).to eq(3)
64+
expect(queries[0]).to eq(query_range: 'query_range_a', label: 'label', unit: 'unit')
65+
expect(queries[1]).to eq(query_range: 'query_range_empty')
66+
expect(queries[2]).to eq(query_range: 'query_range_a')
67+
end
68+
end
69+
70+
shared_examples 'required field' do |field_name|
71+
before do
72+
described_class.instance_variable_set :@additional_metrics_raw, nil
73+
end
74+
75+
context "when #{field_name} is nil" do
76+
before do
77+
allow(described_class).to receive(:load_yaml_file) { YAML.load(field_missing) }
78+
end
79+
80+
it 'throws parsing error' do
81+
expect { subject }.to raise_error(parser_error_class, /missing.*#{field_name}/)
82+
end
83+
end
84+
85+
context "when #{field_name} are not specified" do
86+
before do
87+
allow(described_class).to receive(:load_yaml_file) { YAML.load(field_nil) }
88+
end
89+
90+
it 'throws parsing error' do
91+
expect { subject }.to raise_error(parser_error_class, /missing.*#{field_name}/)
92+
end
93+
end
94+
end
95+
96+
describe 'group required fields' do
97+
it_behaves_like 'required field', :metrics do
98+
let(:field_nil) do
99+
<<-EOF.strip_heredoc
100+
- group: group_a
101+
priority: 1
102+
metrics:
103+
EOF
104+
end
105+
106+
let(:field_missing) do
107+
<<-EOF.strip_heredoc
108+
- group: group_a
109+
priority: 1
110+
EOF
111+
end
112+
end
113+
114+
it_behaves_like 'required field', :group do
115+
let(:field_nil) do
116+
<<-EOF.strip_heredoc
117+
- priority: 1
118+
metrics: []
119+
EOF
120+
end
121+
122+
let(:field_missing) do
123+
<<-EOF.strip_heredoc
124+
- priority: 1
125+
metrics: []
126+
EOF
127+
end
128+
end
129+
130+
it_behaves_like 'required field', :priority do
131+
let(:field_nil) do
132+
<<-EOF.strip_heredoc
133+
- group: group_a
134+
priority:
135+
metrics: []
136+
EOF
137+
end
138+
139+
let(:field_missing) do
140+
<<-EOF.strip_heredoc
141+
- group: group_a
142+
metrics: []
143+
EOF
144+
end
145+
end
146+
end
147+
148+
describe 'metrics fields parsing' do
149+
it_behaves_like 'required field', :title do
150+
let(:field_nil) do
151+
<<-EOF.strip_heredoc
152+
- group: group_a
153+
priority: 1
154+
metrics:
155+
- title:
156+
required_metrics: []
157+
weight: 1
158+
queries: []
159+
EOF
160+
end
161+
162+
let(:field_missing) do
163+
<<-EOF.strip_heredoc
164+
- group: group_a
165+
priority: 1
166+
metrics:
167+
- required_metrics: []
168+
weight: 1
169+
queries: []
170+
EOF
171+
end
172+
end
173+
174+
it_behaves_like 'required field', :required_metrics do
175+
let(:field_nil) do
176+
<<-EOF.strip_heredoc
177+
- group: group_a
178+
priority: 1
179+
metrics:
180+
- title: title
181+
required_metrics:
182+
weight: 1
183+
queries: []
184+
EOF
185+
end
186+
187+
let(:field_missing) do
188+
<<-EOF.strip_heredoc
189+
- group: group_a
190+
priority: 1
191+
metrics:
192+
- title: title
193+
weight: 1
194+
queries: []
195+
EOF
196+
end
197+
end
198+
199+
it_behaves_like 'required field', :weight do
200+
let(:field_nil) do
201+
<<-EOF.strip_heredoc
202+
- group: group_a
203+
priority: 1
204+
metrics:
205+
- title: title
206+
required_metrics: []
207+
weight:
208+
queries: []
209+
EOF
210+
end
211+
212+
let(:field_missing) do
213+
<<-EOF.strip_heredoc
214+
- group: group_a
215+
priority: 1
216+
metrics:
217+
- title: title
218+
required_metrics: []
219+
queries: []
220+
EOF
221+
end
222+
end
223+
224+
it_behaves_like 'required field', :queries do
225+
let(:field_nil) do
226+
<<-EOF.strip_heredoc
227+
- group: group_a
228+
priority: 1
229+
metrics:
230+
- title: title
231+
required_metrics: []
232+
weight: 1
233+
queries:
234+
EOF
235+
end
236+
237+
let(:field_missing) do
238+
<<-EOF.strip_heredoc
239+
- group: group_a
240+
priority: 1
241+
metrics:
242+
- title: title
243+
required_metrics: []
244+
weight: 1
245+
EOF
246+
end
247+
end
248+
end
249+
end
250+
end

spec/support/prometheus/metric_builders.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def simple_metrics(added_metric_name: 'metric_a')
2121
end
2222

2323
def simple_metric_group(name: 'name', metrics: simple_metrics)
24-
Gitlab::Prometheus::MetricGroup.new(name: name, priority: 1, metrics: metrics)
24+
Gitlab::Prometheus::MetricGroup.new( name, 1, metrics)
2525
end
2626
end
2727
end

0 commit comments

Comments
 (0)