1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Metrics::Methods do
subject { Class.new { include Gitlab::Metrics::Methods } }
shared_context 'metric' do |metric_type, *args|
let(:docstring) { 'description' }
let(:metric_name) { :sample_metric }
describe "#define_#{metric_type}" do
define_method(:call_define_metric_method) do |**args|
subject.__send__("define_#{metric_type}", metric_name, **args)
end
context 'metrics access method not defined' do
it "defines metrics accessing method" do
expect(subject).not_to respond_to(metric_name)
call_define_metric_method(docstring: docstring)
expect(subject).to respond_to(metric_name)
end
end
context 'metrics access method defined' do
before do
call_define_metric_method(docstring: docstring)
end
it 'raises error when trying to redefine method' do
expect { call_define_metric_method(docstring: docstring) }.to raise_error(ArgumentError)
end
context 'metric is not cached' do
it 'calls fetch_metric' do
expect(subject).to receive(:init_metric).with(metric_type, metric_name, docstring: docstring)
subject.public_send(metric_name)
end
end
context 'metric is cached' do
before do
subject.public_send(metric_name)
end
it 'returns cached metric' do
expect(subject).not_to receive(:init_metric)
subject.public_send(metric_name)
end
end
end
end
describe "#fetch_#{metric_type}" do
let(:null_metric) { Gitlab::Metrics::NullMetric.instance }
define_method(:call_fetch_metric_method) do |**args|
subject.__send__("fetch_#{metric_type}", metric_name, **args)
end
context "when #{metric_type} is not cached" do
it 'initializes counter metric' do
allow(Gitlab::Metrics).to receive(metric_type).and_return(null_metric)
call_fetch_metric_method(docstring: docstring)
expect(Gitlab::Metrics).to have_received(metric_type).with(metric_name, docstring, *args)
end
end
context "when #{metric_type} is cached" do
before do
call_fetch_metric_method(docstring: docstring)
end
it 'uses class metric cache' do
expect(Gitlab::Metrics).not_to receive(metric_type)
call_fetch_metric_method(docstring: docstring)
end
context 'when metric is reloaded' do
before do
subject.reload_metric!(metric_name)
end
it "initializes #{metric_type} metric" do
allow(Gitlab::Metrics).to receive(metric_type).and_return(null_metric)
call_fetch_metric_method(docstring: docstring)
expect(Gitlab::Metrics).to have_received(metric_type).with(metric_name, docstring, *args)
end
end
end
context 'when metric is configured with feature' do
let(:feature_name) { :some_metric_feature }
let(:metric) { call_fetch_metric_method(docstring: docstring, with_feature: feature_name) }
context 'when feature is enabled' do
before do
stub_feature_flags(feature_name => true)
end
it "initializes #{metric_type} metric" do
allow(Gitlab::Metrics).to receive(metric_type).and_return(null_metric)
metric
expect(Gitlab::Metrics).to have_received(metric_type).with(metric_name, docstring, *args)
end
end
context 'when feature is disabled' do
before do
stub_feature_flags(feature_name => false)
end
it "returns NullMetric" do
allow(Gitlab::Metrics).to receive(metric_type)
expect(metric).to be_instance_of(Gitlab::Metrics::NullMetric)
expect(Gitlab::Metrics).not_to have_received(metric_type)
end
end
end
end
end
include_examples 'metric', :counter, {}
include_examples 'metric', :gauge, {}, :all
include_examples 'metric', :histogram, {}, [0.005, 0.01, 0.1, 1, 10]
end
|