blob: 448246ff513c14bd617384b5e7a796111f84e207 (
plain)
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
140
141
142
143
144
145
146
147
148
149
|
require 'spec_helper'
describe Gitlab::Metrics::MethodCall do
let(:transaction) { double(:transaction, labels: {}) }
let(:method_call) { described_class.new('Foo#bar', :Foo, '#bar', transaction) }
describe '#measure' do
it 'measures the performance of the supplied block' do
method_call.measure { 'foo' }
expect(method_call.real_time).to be_a_kind_of(Numeric)
expect(method_call.cpu_time).to be_a_kind_of(Numeric)
expect(method_call.call_count).to eq(1)
end
context 'when measurement is above threshold' do
before do
allow(method_call).to receive(:above_threshold?).and_return(true)
end
context 'prometheus instrumentation is enabled' do
before do
Feature.get(:prometheus_metrics_method_instrumentation).enable
end
it 'observes the performance of the supplied block' do
expect(described_class.call_duration_histogram)
.to receive(:observe)
.with({ module: :Foo, method: '#bar' }, be_a_kind_of(Numeric))
method_call.measure { 'foo' }
end
end
context 'prometheus instrumentation is disabled' do
before do
Feature.get(:prometheus_metrics_method_instrumentation).disable
end
it 'does not observe the performance' do
expect(described_class.call_duration_histogram)
.not_to receive(:observe)
method_call.measure { 'foo' }
end
end
end
context 'when measurement is below threshold' do
before do
allow(method_call).to receive(:above_threshold?).and_return(false)
Feature.get(:prometheus_metrics_method_instrumentation).enable
end
it 'does not observe the performance' do
expect(described_class.call_duration_histogram)
.not_to receive(:observe)
method_call.measure { 'foo' }
end
end
end
describe '#to_metric' do
it 'returns a Metric instance' do
expect(method_call).to receive(:real_time).and_return(4.0001)
expect(method_call).to receive(:cpu_time).and_return(3.0001)
method_call.measure { 'foo' }
metric = method_call.to_metric
expect(metric).to be_an_instance_of(Gitlab::Metrics::Metric)
expect(metric.series).to eq('rails_method_calls')
expect(metric.values[:duration]).to eq(4000)
expect(metric.values[:cpu_duration]).to eq(3000)
expect(metric.values[:call_count]).to be_an(Integer)
expect(metric.tags).to eq({ method: 'Foo#bar' })
end
end
describe '#above_threshold?' do
before do
allow(Gitlab::Metrics).to receive(:method_call_threshold).and_return(100)
end
it 'returns false when the total call time is not above the threshold' do
expect(method_call).to receive(:real_time).and_return(0.009)
expect(method_call.above_threshold?).to eq(false)
end
it 'returns true when the total call time is above the threshold' do
expect(method_call).to receive(:real_time).and_return(9)
expect(method_call.above_threshold?).to eq(true)
end
end
describe '#call_count' do
context 'without any method calls' do
it 'returns 0' do
expect(method_call.call_count).to eq(0)
end
end
context 'with method calls' do
it 'returns the number of method calls' do
method_call.measure { 'foo' }
expect(method_call.call_count).to eq(1)
end
end
end
describe '#cpu_time' do
context 'without timings' do
it 'returns 0.0' do
expect(method_call.cpu_time).to eq(0.0)
end
end
context 'with timings' do
it 'returns the total CPU time' do
method_call.measure { 'foo' }
expect(method_call.cpu_time >= 0.0).to be(true)
end
end
end
describe '#real_time' do
context 'without timings' do
it 'returns 0.0' do
expect(method_call.real_time).to eq(0.0)
end
end
context 'with timings' do
it 'returns the total real time' do
method_call.measure { 'foo' }
expect(method_call.real_time >= 0.0).to be(true)
end
end
end
end
|