riemann-client 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/spec/client.rb DELETED
@@ -1,384 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # How to run the bacon tests:
5
- # 1. Start Riemann using the config from riemann.config
6
- # 2. $ bundle exec bacon spec/client.rb
7
-
8
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'riemann'))
9
- require 'riemann/client'
10
- require 'bacon'
11
- require 'set'
12
- require 'timecop'
13
-
14
- Bacon.summary_on_exit
15
-
16
- include Riemann # rubocop:disable Style/MixinUsage
17
-
18
- INACTIVITY_TIME = 5
19
-
20
- def wait_for(&block)
21
- tries = 0
22
- while tries < 30
23
- tries += 1
24
- begin
25
- res = block.call
26
- return res if res
27
- rescue NoMethodError
28
- # If a query returns no result (#query retruns nil or #[] returns []),
29
- # calling #first on it will raise a NoMethodError. We can ignore it for
30
- # these tests.
31
- end
32
- sleep(0.1)
33
- end
34
-
35
- raise 'wait_for condition never realized'
36
- end
37
-
38
- def roundtrip_metric(metric)
39
- @client_with_transport << {
40
- service: 'metric-test',
41
- metric: metric
42
- }
43
-
44
- wait_for { @client["service = \"metric-test\" and metric = #{metric}"].first }
45
- .metric.should.equal metric
46
- end
47
-
48
- def truthy
49
- ->(obj) { !(obj.nil? || obj == false) }
50
- end
51
-
52
- def falsey
53
- ->(obj) { obj.nil? || obj == false }
54
- end
55
-
56
- shared 'a riemann client' do
57
- should 'yield itself to given block' do
58
- client = nil
59
- Client.new(host: 'localhost', port: 5555) do |c|
60
- client = c
61
- end
62
- client.should.be.is_a?(Client)
63
- client.should.not.be.connected
64
- end
65
-
66
- should 'close sockets if given a block that raises' do
67
- client = nil
68
- begin
69
- Client.new(host: 'localhost', port: 5555) do |c|
70
- client = c
71
- raise 'The Boom'
72
- end
73
- rescue StandardError
74
- # swallow the exception
75
- end
76
- client.should.be.is_a?(Client)
77
- client.should.not.be.connected
78
- end
79
-
80
- should 'be connected after sending' do
81
- @client_with_transport.connected?.should.be falsey
82
- @client.connected?.should.be falsey
83
- @client_with_transport << { state: 'ok', service: 'connected check' }
84
- @client_with_transport.connected?.should.be truthy
85
- # NOTE: only single transport connected at this point, @client.connected? is still false until all transports used
86
- end
87
-
88
- should 'send longs' do
89
- roundtrip_metric(0)
90
- roundtrip_metric(-3)
91
- roundtrip_metric(5)
92
- roundtrip_metric(-(2**63))
93
- roundtrip_metric(2**63 - 1)
94
- end
95
-
96
- should 'send doubles' do
97
- roundtrip_metric 0.0
98
- roundtrip_metric 12.0
99
- roundtrip_metric 1.2300000190734863
100
- end
101
-
102
- should 'send custom attributes' do
103
- event = Event.new(
104
- service: 'custom',
105
- state: 'ok',
106
- cats: 'meow',
107
- env: 'prod'
108
- )
109
- event[:sneak] = 'attack'
110
- @client_with_transport << event
111
- event2 = wait_for { @client['service = "custom"'].first }
112
- event2.service.should.equal 'custom'
113
- event2.state.should.equal 'ok'
114
- event2[:cats].should.equal 'meow'
115
- event2[:env].should.equal 'prod'
116
- event2[:sneak].should.equal 'attack'
117
- end
118
-
119
- should 'send a state with a time' do
120
- Timecop.freeze do
121
- t = (Time.now - 10).to_i
122
- @client_with_transport << {
123
- state: 'ok',
124
- service: 'test',
125
- time: t
126
- }
127
- wait_for { @client.query('service = "test"').events.first.time == t }
128
- e = @client.query('service = "test"').events.first
129
- e.time.should.equal t
130
- e.time_micros.should.equal t * 1_000_000
131
- end
132
- end
133
-
134
- should 'send a state with a time_micros' do
135
- Timecop.freeze do
136
- t = ((Time.now - 10).to_f * 1_000_000).to_i
137
- @client_with_transport << {
138
- state: 'ok',
139
- service: 'test',
140
- time_micros: t
141
- }
142
- wait_for { @client.query('service = "test"').events.first.time_micros == t }
143
- e = @client.query('service = "test"').events.first
144
- e.time.should.equal (Time.now - 10).to_i
145
- e.time_micros.should.equal t
146
- end
147
- end
148
-
149
- should 'send a state without time nor time_micros' do
150
- time_before = (Time.now.to_f * 1_000_000).to_i
151
- @client_with_transport << {
152
- state: 'ok',
153
- service: 'timeless test'
154
- }
155
- wait_for { @client.query('service = "timeless test"').events.first.time_micros >= time_before }
156
- e = @client.query('service = "timeless test"').events.first
157
- time_after = (Time.now.to_f * 1_000_000).to_i
158
-
159
- [time_before, e.time_micros, time_after].sort.should.equal([time_before, e.time_micros, time_after])
160
- end
161
-
162
- should 'query states' do
163
- @client_with_transport << { state: 'critical', service: '1' }
164
- @client_with_transport << { state: 'warning', service: '2' }
165
- @client_with_transport << { state: 'critical', service: '3' }
166
- wait_for { @client.query('service = "3"').events.first }
167
- @client.query.events
168
- .map(&:service).to_set.should.superset %w[1 2 3].to_set
169
- @client.query('state = "critical" and (service = "1" or service = "2" or service = "3")').events
170
- .map(&:service).to_set.should.equal %w[1 3].to_set
171
- end
172
-
173
- it '[]' do
174
- # @client['state = "critical"'].should == []
175
- @client_with_transport << { state: 'critical' }
176
- wait_for { @client['state = "critical"'].first }.state.should.equal 'critical'
177
- end
178
-
179
- should 'query quickly' do
180
- t1 = Time.now
181
- total = 1000
182
- total.times do |_i|
183
- @client.query('state = "critical"')
184
- end
185
- t2 = Time.now
186
-
187
- rate = total / (t2 - t1)
188
- puts "\n #{format('%.2f', rate)} queries/sec (#{format('%.2f', (1000 / rate))}ms per query)"
189
- rate.should > 100
190
- end
191
-
192
- should 'be threadsafe' do
193
- concurrency = 10
194
- per_thread = 200
195
- total = concurrency * per_thread
196
-
197
- t1 = Time.now
198
- (0...concurrency).map do |_i|
199
- Thread.new do
200
- per_thread.times do
201
- @client_with_transport.<<({
202
- state: 'ok',
203
- service: 'test',
204
- description: 'desc',
205
- metric_f: 1.0
206
- })
207
- end
208
- end
209
- end.each(&:join)
210
- t2 = Time.now
211
-
212
- rate = total / (t2 - t1)
213
- puts "\n #{format('%.2f', rate)} inserts/sec (#{format('%.2f', (1000 / rate))}ms per insert)"
214
- rate.should > @expected_rate
215
- end
216
- end
217
-
218
- describe 'Riemann::Client (TLS transport)' do
219
- before do
220
- @client = Client.new(host: 'localhost', port: 5554, ssl: true,
221
- key_file: '/etc/riemann/riemann_server.pkcs8',
222
- cert_file: '/etc/riemann/riemann_server.crt',
223
- ca_file: '/etc/riemann/riemann_server.crt',
224
- ssl_verify: true)
225
- @client_with_transport = @client.tcp
226
- @expected_rate = 100
227
- end
228
- behaves_like 'a riemann client'
229
-
230
- should 'send a state' do
231
- res = @client_with_transport << {
232
- state: 'ok',
233
- service: 'test',
234
- description: 'desc',
235
- metric_f: 1.0
236
- }
237
-
238
- res.ok.should.be truthy
239
- wait_for { @client['service = "test"'].first }.state.should.equal 'ok'
240
- end
241
-
242
- should 'survive inactivity' do
243
- @client_with_transport.<<({
244
- state: 'warning',
245
- service: 'survive TCP inactivity'
246
- })
247
- wait_for { @client['service = "survive TCP inactivity"'].first.state == 'warning' }
248
-
249
- sleep INACTIVITY_TIME
250
-
251
- @client_with_transport.<<({
252
- state: 'ok',
253
- service: 'survive TCP inactivity'
254
- }).ok.should.be truthy
255
- wait_for { @client['service = "survive TCP inactivity"'].first.state == 'ok' }
256
- end
257
-
258
- should 'survive local close' do
259
- @client_with_transport.<<({
260
- state: 'warning',
261
- service: 'survive TCP local close'
262
- }).ok.should.be truthy
263
- wait_for { @client['service = "survive TCP local close"'].first.state == 'warning' }
264
-
265
- @client.close
266
-
267
- @client_with_transport.<<({
268
- state: 'ok',
269
- service: 'survive TCP local close'
270
- }).ok.should.be truthy
271
- wait_for { @client['service = "survive TCP local close"'].first.state == 'ok' }
272
- end
273
- end
274
-
275
- describe 'Riemann::Client (TCP transport)' do
276
- before do
277
- @client = Client.new(host: 'localhost', port: 5555)
278
- @client_with_transport = @client.tcp
279
- @expected_rate = 100
280
- end
281
- behaves_like 'a riemann client'
282
-
283
- should 'send a state' do
284
- res = @client_with_transport << {
285
- state: 'ok',
286
- service: 'test',
287
- description: 'desc',
288
- metric_f: 1.0
289
- }
290
-
291
- res.ok.should.be truthy
292
- wait_for { @client['service = "test"'].first }.state.should.equal 'ok'
293
- end
294
-
295
- should 'survive inactivity' do
296
- @client_with_transport.<<({
297
- state: 'warning',
298
- service: 'survive TCP inactivity'
299
- })
300
- wait_for { @client['service = "survive TCP inactivity"'].first.state == 'warning' }
301
-
302
- sleep INACTIVITY_TIME
303
-
304
- @client_with_transport.<<({
305
- state: 'ok',
306
- service: 'survive TCP inactivity'
307
- }).ok.should.be truthy
308
- wait_for { @client['service = "survive TCP inactivity"'].first.state == 'ok' }
309
- end
310
-
311
- should 'survive local close' do
312
- @client_with_transport.<<({
313
- state: 'warning',
314
- service: 'survive TCP local close'
315
- }).ok.should.be truthy
316
- wait_for { @client['service = "survive TCP local close"'].first.state == 'warning' }
317
-
318
- @client.close
319
-
320
- @client_with_transport.<<({
321
- state: 'ok',
322
- service: 'survive TCP local close'
323
- }).ok.should.be truthy
324
- wait_for { @client['service = "survive TCP local close"'].first.state == 'ok' }
325
- end
326
- end
327
-
328
- describe 'Riemann::Client (UDP transport)' do
329
- before do
330
- @client = Client.new(host: 'localhost', port: 5555)
331
- @client_with_transport = @client.udp
332
- @expected_rate = 1000
333
- end
334
- behaves_like 'a riemann client'
335
-
336
- should 'send a state' do
337
- res = @client_with_transport << {
338
- state: 'ok',
339
- service: 'test',
340
- description: 'desc',
341
- metric_f: 1.0
342
- }
343
-
344
- res.should.be.nil
345
- wait_for { @client['service = "test"'].first }.state.should.equal 'ok'
346
- end
347
-
348
- should 'survive inactivity' do
349
- @client_with_transport.<<({
350
- state: 'warning',
351
- service: 'survive UDP inactivity'
352
- }).should.be.nil
353
- wait_for { @client['service = "survive UDP inactivity"'].first.state == 'warning' }
354
-
355
- sleep INACTIVITY_TIME
356
-
357
- @client_with_transport.<<({
358
- state: 'ok',
359
- service: 'survive UDP inactivity'
360
- }).should.be.nil
361
- wait_for { @client['service = "survive UDP inactivity"'].first.state == 'ok' }
362
- end
363
-
364
- should 'survive local close' do
365
- @client_with_transport.<<({
366
- state: 'warning',
367
- service: 'survive UDP local close'
368
- }).should.be.nil
369
- wait_for { @client['service = "survive UDP local close"'].first.state == 'warning' }
370
-
371
- @client.close
372
-
373
- @client_with_transport.<<({
374
- state: 'ok',
375
- service: 'survive UDP local close'
376
- }).should.be.nil
377
- wait_for { @client['service = "survive UDP local close"'].first.state == 'ok' }
378
- end
379
-
380
- should 'raise Riemann::Client::Unsupported exception on query' do
381
- should.raise(Riemann::Client::Unsupported) { @client_with_transport['service = "test"'] }
382
- should.raise(Riemann::Client::Unsupported) { @client_with_transport.query('service = "test"') }
383
- end
384
- end