-
Notifications
You must be signed in to change notification settings - Fork 154
Expand file tree
/
Copy pathcollector_spec.rb
More file actions
175 lines (132 loc) · 5.29 KB
/
Copy pathcollector_spec.rb
File metadata and controls
175 lines (132 loc) · 5.29 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# encoding: UTF-8
require 'rack/test'
require 'prometheus/middleware/collector'
describe Prometheus::Middleware::Collector do
include Rack::Test::Methods
# Reset the data store
before do
Prometheus::Client.config.data_store = Prometheus::Client::DataStores::Synchronized.new
end
let(:registry) do
Prometheus::Client::Registry.new
end
let(:original_app) do
->(_) { [200, { 'Content-Type' => 'text/html' }, ['OK']] }
end
let!(:app) do
described_class.new(original_app, registry: registry)
end
let(:dummy_error) { RuntimeError.new("Dummy error from tests") }
it 'returns the app response' do
get '/foo'
expect(last_response).to be_ok
expect(last_response.body).to eql('OK')
end
it 'handles errors in the registry gracefully' do
counter = registry.get(:http_server_requests_total)
expect(counter).to receive(:increment).and_raise(dummy_error)
get '/foo'
expect(last_response).to be_ok
end
it 'traces request information' do
expect(Benchmark).to receive(:realtime).and_yield.and_return(0.2)
get '/foo'
metric = :http_server_requests_total
labels = { method: 'get', path: '/foo', code: '200' }
expect(registry.get(metric).get(labels: labels)).to eql(1.0)
metric = :http_server_request_duration_seconds
labels = { method: 'get', path: '/foo' }
expect(registry.get(metric).get(labels: labels)).to include("0.1" => 0, "0.25" => 1)
end
it 'includes SCRIPT_NAME in the path if provided' do
metric = :http_server_requests_total
get '/foo'
expect(registry.get(metric).values.keys.last[:path]).to eql("/foo")
env('SCRIPT_NAME', '/engine')
get '/foo'
env('SCRIPT_NAME', nil)
expect(registry.get(metric).values.keys.last[:path]).to eql("/engine/foo")
end
it 'normalizes paths containing numeric IDs by default' do
expect(Benchmark).to receive(:realtime).and_yield.and_return(0.3)
get '/foo/42/bars'
metric = :http_server_requests_total
labels = { method: 'get', path: '/foo/:id/bars', code: '200' }
expect(registry.get(metric).get(labels: labels)).to eql(1.0)
metric = :http_server_request_duration_seconds
labels = { method: 'get', path: '/foo/:id/bars' }
expect(registry.get(metric).get(labels: labels)).to include("0.1" => 0, "0.5" => 1)
end
it 'normalizes paths containing UUIDs by default' do
expect(Benchmark).to receive(:realtime).and_yield.and_return(0.3)
get '/foo/5180349d-a491-4d73-af30-4194a46bdff3/bars'
metric = :http_server_requests_total
labels = { method: 'get', path: '/foo/:uuid/bars', code: '200' }
expect(registry.get(metric).get(labels: labels)).to eql(1.0)
metric = :http_server_request_duration_seconds
labels = { method: 'get', path: '/foo/:uuid/bars' }
expect(registry.get(metric).get(labels: labels)).to include("0.1" => 0, "0.5" => 1)
end
it 'handles consecutive path segments containing IDs' do
expect(Benchmark).to receive(:realtime).and_yield.and_return(0.3)
get '/foo/42/24'
metric = :http_server_requests_total
labels = { method: 'get', path: '/foo/:id/:id', code: '200' }
expect(registry.get(metric).get(labels: labels)).to eql(1.0)
metric = :http_server_request_duration_seconds
labels = { method: 'get', path: '/foo/:id/:id' }
expect(registry.get(metric).get(labels: labels)).to include("0.1" => 0, "0.5" => 1)
end
it 'handles consecutive path segments containing UUIDs' do
expect(Benchmark).to receive(:realtime).and_yield.and_return(0.3)
get '/foo/5180349d-a491-4d73-af30-4194a46bdff3/5180349d-a491-4d73-af30-4194a46bdff2'
metric = :http_server_requests_total
labels = { method: 'get', path: '/foo/:uuid/:uuid', code: '200' }
expect(registry.get(metric).get(labels: labels)).to eql(1.0)
metric = :http_server_request_duration_seconds
labels = { method: 'get', path: '/foo/:uuid/:uuid' }
expect(registry.get(metric).get(labels: labels)).to include("0.1" => 0, "0.5" => 1)
end
context 'when the app raises an exception' do
let(:original_app) do
lambda do |env|
raise dummy_error if env['PATH_INFO'] == '/broken'
[200, { 'Content-Type' => 'text/html' }, ['OK']]
end
end
before do
get '/foo'
end
it 'traces exceptions' do
expect { get '/broken' }.to raise_error RuntimeError
metric = :http_server_exceptions_total
labels = { exception: 'RuntimeError' }
expect(registry.get(metric).get(labels: labels)).to eql(1.0)
end
end
context 'when provided a custom metrics_prefix' do
let!(:app) do
described_class.new(
original_app,
registry: registry,
metrics_prefix: 'lolrus',
)
end
it 'provides alternate metric names' do
expect(
registry.get(:lolrus_requests_total),
).to be_a(Prometheus::Client::Counter)
expect(
registry.get(:lolrus_request_duration_seconds),
).to be_a(Prometheus::Client::Histogram)
expect(
registry.get(:lolrus_exceptions_total),
).to be_a(Prometheus::Client::Counter)
end
it "doesn't register the default metrics" do
expect(registry.get(:http_server_requests_total)).to be(nil)
expect(registry.get(:http_server_request_duration_seconds)).to be(nil)
expect(registry.get(:http_server_exceptions_total)).to be(nil)
end
end
end