logstash-output-sumologic 1.1.4 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/sumologic"
4
+
5
+ describe LogStash::Outputs::SumoLogic::MessageQueue do
6
+
7
+ context "working in pile mode if interval > 0 && pile_max > 0" do
8
+
9
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
10
+
11
+ it "enq() correctly" do
12
+ queue = LogStash::Outputs::SumoLogic::MessageQueue.new(stats, "queue_max" => 10)
13
+ 10.times { |i|
14
+ queue.enq("test - #{i}")
15
+ expect(queue.size()).to eq(i + 1)
16
+ expect(stats.total_enque_times.value).to eq(i + 1)
17
+ }
18
+ end
19
+
20
+ it "deq() correctly" do
21
+ queue = LogStash::Outputs::SumoLogic::MessageQueue.new(stats, "queue_max" => 10)
22
+ 10.times { |i|
23
+ queue.enq("test - #{i}")
24
+ }
25
+ 10.times { |i|
26
+ expect(queue.size()).to eq(10 - i)
27
+ result = queue.deq()
28
+ expect(result).to eq("test - #{i}")
29
+ expect(stats.total_deque_times.value).to eq(i + 1)
30
+ }
31
+ end
32
+
33
+ it "drain() correctly" do
34
+ queue = LogStash::Outputs::SumoLogic::MessageQueue.new(stats, "queue_max" => 10)
35
+ 10.times { |i|
36
+ queue.enq("test - #{i}")
37
+ }
38
+ result = queue.drain()
39
+ expect(queue.size()).to eq(0)
40
+ expect(stats.total_deque_times.value).to eq(10)
41
+ expect(result.size).to eq(10)
42
+ 10.times { |i|
43
+ expect(result[i]).to eq("test - #{i}")
44
+ }
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,523 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/sumologic"
4
+
5
+ describe LogStash::Outputs::SumoLogic::PayloadBuilder do
6
+
7
+ result = ""
8
+
9
+ before :each do
10
+ result = builder.build(event)
11
+ end
12
+
13
+ context "should build log payload in default format" do
14
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
15
+ let(:builder) { LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats, "url" => "http://localhost/1234") }
16
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
17
+
18
+ it "start with a valid timestamp" do
19
+ ts = result.split(" ")[0]
20
+ DateTime.parse(ts)
21
+ end
22
+
23
+ it "end with host and message" do
24
+ expect(result).to end_with("myHost Hello world")
25
+ end
26
+
27
+ end # context
28
+
29
+ context "should build log payload with @json tag" do
30
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
31
+ let(:builder) { LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats, "url" => "http://localhost/1234", "format" => "%{@json}") }
32
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
33
+
34
+ it "include host field" do
35
+ expect(result).to include("\"host\":\"myHost\"")
36
+ end
37
+
38
+ it "include host field" do
39
+ expect(result).to include("\"message\":\"Hello world\"")
40
+ end
41
+
42
+ it "include host field" do
43
+ expect(result).to include("\"@timestamp\"")
44
+ end
45
+
46
+ end # context
47
+
48
+ context "should build log payload with customized format" do
49
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
50
+ let(:builder) { LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats, "url" => "http://localhost/1234", "format" => "%{@timestamp} %{foo} %{bar}") }
51
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
52
+
53
+ it "start with a valid timestamp" do
54
+ ts = result.split(" ")[0]
55
+ DateTime.parse(ts)
56
+ end
57
+
58
+ it "end with host and message" do
59
+ expect(result).to end_with("fancy 24")
60
+ end
61
+
62
+ end # context
63
+
64
+ context "should build log payload with customized json_mapping" do
65
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
66
+ let(:builder) {
67
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
68
+ "url" => "http://localhost/1234",
69
+ "format" => "%{host} %{@json}",
70
+ "json_mapping" => {
71
+ "foo" => "%{foo}",
72
+ "bar" => "%{bar}",
73
+ "%{foo}" => "%{bar}"
74
+ })
75
+ }
76
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
77
+
78
+ specify {
79
+ expect(result).to eq("myHost {\"foo\":\"fancy\",\"bar\":\"24\",\"fancy\":\"24\"}")
80
+ }
81
+
82
+ end # context
83
+
84
+ context "should build metrics payload with graphite format" do
85
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
86
+ let(:builder) {
87
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
88
+ "url" => "http://localhost/1234",
89
+ "metrics" => {
90
+ "hurray.%{foo}" => "%{bar}"
91
+ },
92
+ "metrics_format" => "graphite")
93
+ }
94
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
95
+
96
+ it "start with metrics name and value" do
97
+ expect(result).to start_with("hurray.fancy 24 ")
98
+ end
99
+
100
+ it "end with epoch timestamp" do
101
+ expect(result).to match(/\d{10,}$/)
102
+ end
103
+
104
+ end # context
105
+
106
+ context "should build metrics payload with carbon2 format" do
107
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
108
+ let(:builder) {
109
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
110
+ "url" => "http://localhost/1234",
111
+ "metrics" => {
112
+ "hurray.%{foo}" => "%{bar}"
113
+ })
114
+ }
115
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
116
+
117
+ it "start with metrics name and value" do
118
+ expect(result).to start_with("metric=hurray.fancy 24 ")
119
+ end
120
+
121
+ it "end with epoch timestamp" do
122
+ expect(result).to match(/\d{10,}$/)
123
+ end
124
+
125
+ end # context
126
+
127
+ context "should build metrics payload with metrics_name override" do
128
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
129
+ let(:builder) {
130
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
131
+ "url" => "http://localhost/1234",
132
+ "metrics" => {
133
+ "hurray.%{foo}" => "%{bar}"
134
+ },
135
+ "metrics_name" => "mynamespace.*")
136
+ }
137
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
138
+
139
+ it "start with modified metrics name and value" do
140
+ expect(result).to start_with("metric=mynamespace.hurray.fancy 24 ")
141
+ end
142
+
143
+ it "end with epoch timestamp" do
144
+ expect(result).to match(/\d{10,}$/)
145
+ end
146
+
147
+ end # context
148
+
149
+ context "should build metrics payload with intrinsic_tags override" do
150
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
151
+ let(:builder) {
152
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
153
+ "url" => "http://localhost/1234",
154
+ "metrics" => {
155
+ "bar" => "%{bar}"
156
+ },
157
+ "intrinsic_tags" => {
158
+ "host" => "%{host}"
159
+ })
160
+ }
161
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
162
+
163
+ it "start with modified intrinsic tags and value" do
164
+ expect(result).to start_with("host=myHost metric=bar 24 ")
165
+ end
166
+
167
+ it "end with epoch timestamp" do
168
+ expect(result).to match(/\d{10,}$/)
169
+ end
170
+
171
+ end # context
172
+
173
+ context "should build metrics payload with meta_tags override" do
174
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
175
+ let(:builder) {
176
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
177
+ "url" => "http://localhost/1234",
178
+ "metrics" => {
179
+ "bar" => "%{bar}"
180
+ },
181
+ "intrinsic_tags" => {
182
+ "host" => "%{host}"
183
+ },
184
+ "meta_tags" => {
185
+ "foo" => "%{foo}"
186
+ })
187
+ }
188
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
189
+
190
+ it "start with modified intrinsic/meta tags and value" do
191
+ expect(result).to start_with("host=myHost metric=bar foo=fancy 24 ")
192
+ end
193
+
194
+ it "end with epoch timestamp" do
195
+ expect(result).to match(/\d{10,}$/)
196
+ end
197
+
198
+ end # context
199
+
200
+ context "should build metrics payload with multi lines with different values (graphite)" do
201
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
202
+ let(:builder) {
203
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
204
+ "url" => "http://localhost/1234",
205
+ "metrics" => {
206
+ "cpu1" => "%{cpu1}",
207
+ "cpu2" => "%{cpu2}"
208
+ },
209
+ "metrics_name" => "mynamespace.*",
210
+ "metrics_format" => "graphite")
211
+ }
212
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => 0.11) }
213
+
214
+ specify {
215
+ lines = result.split(/\n/).sort
216
+ expect(lines.length).to eq(2)
217
+ expect(lines.shift).to match(/^mynamespace\.cpu1 0\.24 \d{10,}$/)
218
+ expect(lines.shift).to match(/^mynamespace\.cpu2 0\.11 \d{10,}$/)
219
+ }
220
+
221
+ end # context
222
+
223
+ context "should build metrics payload with multi lines with different values (carbon2)" do
224
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
225
+ let(:builder) {
226
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
227
+ "url" => "http://localhost/1234",
228
+ "metrics" => {
229
+ "cpu1" => "%{cpu1}",
230
+ "cpu2" => "%{cpu2}"
231
+ },
232
+ "intrinsic_tags" => {
233
+ "host" => "%{host}"
234
+ },
235
+ "meta_tags" => {
236
+ "foo" => "%{foo}"
237
+ })
238
+ }
239
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => 0.11) }
240
+
241
+ specify {
242
+ lines = result.split(/\n/).sort
243
+ expect(lines.length).to eq(2)
244
+ expect(lines.shift).to match(/^host=myHost metric=cpu1 foo=fancy 0\.24 \d{10,}$/)
245
+ expect(lines.shift).to match(/^host=myHost metric=cpu2 foo=fancy 0\.11 \d{10,}$/)
246
+ }
247
+
248
+ end # context
249
+
250
+ context "should build metrics payload with non-number value dropped (graphite)" do
251
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
252
+ let(:builder) {
253
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
254
+ "url" => "http://localhost/1234",
255
+ "metrics" => {
256
+ "cpu1" => "%{cpu1}",
257
+ "cpu2" => "%{cpu2}",
258
+ "cpu3" => "%{cpu3}"
259
+ },
260
+ "metrics_format" => "graphite")
261
+ }
262
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => "abc", "cpu3" => 0.11) }
263
+
264
+ it "include all points" do
265
+ lines = result.split(/\n/).sort
266
+ expect(lines.length).to eq(2)
267
+ expect(lines.shift).to match(/^cpu1 0\.24 \d{10,}$/)
268
+ expect(lines.shift).to match(/^cpu3 0\.11 \d{10,}$/)
269
+ end
270
+
271
+ end # context
272
+
273
+ context "should build metrics payload with non-number value dropped (carbon2)" do
274
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
275
+ let(:builder) {
276
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
277
+ "url" => "http://localhost/1234",
278
+ "metrics" => {
279
+ "cpu1" => "%{cpu1}",
280
+ "cpu2" => "%{cpu2}",
281
+ "cpu3" => "%{cpu3}"
282
+ },
283
+ "intrinsic_tags" => {
284
+ "host" => "%{host}"
285
+ },
286
+ "metrics_name" => "mynamespace.*",
287
+ "meta_tags" => {
288
+ "foo" => "%{foo}"
289
+ })
290
+ }
291
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => "abc", "cpu3" => 0.11) }
292
+
293
+ specify {
294
+ lines = result.split(/\n/).sort
295
+ expect(lines.length).to eq(2)
296
+ expect(lines.shift).to match(/^host=myHost metric=mynamespace\.cpu1 foo=fancy 0\.24 \d{10,}$/)
297
+ expect(lines.shift).to match(/^host=myHost metric=mynamespace\.cpu3 foo=fancy 0\.11 \d{10,}$/)
298
+ }
299
+
300
+ end # context
301
+
302
+ context "should build metrics payload with fields_as_metrics (graphite)" do
303
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
304
+ let(:builder) {
305
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
306
+ "url" => "http://localhost/1234",
307
+ "fields_as_metrics" => true,
308
+ "metrics_format" => "graphite")
309
+ }
310
+ let(:event) {
311
+ LogStash::Event.new(
312
+ "host" => "myHost",
313
+ "foo" => "fancy",
314
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
315
+ "storageRW" => 51,
316
+ "bar" => "blahblah",
317
+ "blkio" => {
318
+ "write_ps" => 0,
319
+ "read_ps" => 0,
320
+ "total_ps" => 0
321
+ })
322
+ }
323
+
324
+ specify {
325
+ lines = result.split(/\n/).sort
326
+ expect(lines.length).to eq(8)
327
+ expect(lines.shift).to match(/^blkio\.read_ps 0 \d{10,}$/)
328
+ expect(lines.shift).to match(/^blkio\.total_ps 0 \d{10,}$/)
329
+ expect(lines.shift).to match(/^blkio\.write_ps 0 \d{10,}$/)
330
+ expect(lines.shift).to match(/^cpu\.0 0\.24 \d{10,}$/)
331
+ expect(lines.shift).to match(/^cpu\.1 0\.11 \d{10,}$/)
332
+ expect(lines.shift).to match(/^cpu\.2 0\.75 \d{10,}$/)
333
+ expect(lines.shift).to match(/^cpu\.3 0\.28 \d{10,}$/)
334
+ expect(lines.shift).to match(/^storageRW 51 \d{10,}$/)
335
+ }
336
+
337
+ end # context
338
+
339
+ context "should build metrics payload with fields_as_metrics (carbon2)" do
340
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
341
+ let(:builder) {
342
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
343
+ "url" => "http://localhost/1234",
344
+ "fields_as_metrics" => true,
345
+ "intrinsic_tags" => {
346
+ "host"=>"%{host}"
347
+ },
348
+ "meta_tags" => {
349
+ "foo" => "%{foo}"
350
+ })
351
+ }
352
+ let(:event) {
353
+ LogStash::Event.new(
354
+ "host" => "myHost",
355
+ "foo" => "fancy",
356
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
357
+ "storageRW" => 51,
358
+ "bar" => "blahblah",
359
+ "blkio" => {
360
+ "write_ps" => 5,
361
+ "read_ps" => 2,
362
+ "total_ps" => 0
363
+ })
364
+ }
365
+
366
+ specify {
367
+ lines = result.split(/\n/).sort
368
+ expect(lines.length).to eq(8)
369
+ expect(lines.shift).to match(/^host=myHost metric=blkio\.read_ps foo=fancy 2 \d{10,}$/)
370
+ expect(lines.shift).to match(/^host=myHost metric=blkio\.total_ps foo=fancy 0 \d{10,}$/)
371
+ expect(lines.shift).to match(/^host=myHost metric=blkio\.write_ps foo=fancy 5 \d{10,}$/)
372
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
373
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.1 foo=fancy 0\.11 \d{10,}$/)
374
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
375
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
376
+ expect(lines.shift).to match(/^host=myHost metric=storageRW foo=fancy 51 \d{10,}$/)
377
+ }
378
+
379
+ end # context
380
+
381
+ context "should hornor fields_include when fields_as_metrics (graphite)" do
382
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
383
+ let(:builder) {
384
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
385
+ "url" => "http://localhost/1234",
386
+ "fields_as_metrics" => true,
387
+ "metrics_format" => "graphite",
388
+ "fields_include" => ["cpu*"])
389
+ }
390
+ let(:event) {
391
+ LogStash::Event.new(
392
+ "host" => "myHost",
393
+ "foo" => "fancy",
394
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
395
+ "storageRW" => 51,
396
+ "bar" => "blahblah",
397
+ "blkio" => {
398
+ "write_ps" => 5,
399
+ "read_ps" => 2,
400
+ "total_ps" => 0
401
+ })
402
+ }
403
+
404
+ specify {
405
+ lines = result.split(/\n/).sort
406
+ expect(lines.length).to eq(4)
407
+ expect(lines.shift).to match(/^cpu\.0 0\.24 \d{10,}$/)
408
+ expect(lines.shift).to match(/^cpu\.1 0\.11 \d{10,}$/)
409
+ expect(lines.shift).to match(/^cpu\.2 0\.75 \d{10,}$/)
410
+ expect(lines.shift).to match(/^cpu\.3 0\.28 \d{10,}$/)
411
+ }
412
+
413
+ end # context
414
+
415
+ context "should hornor fields_include when fields_as_metrics (carbon2)" do
416
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
417
+ let(:builder) {
418
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
419
+ "url" => "http://localhost/1234",
420
+ "fields_as_metrics" => true,
421
+ "intrinsic_tags" => {
422
+ "host" => "%{host}"
423
+ },
424
+ "meta_tags" => {
425
+ "foo" => "%{foo}"
426
+ },
427
+ "fields_include" => ["cpu*"])
428
+ }
429
+ let(:event) {
430
+ LogStash::Event.new(
431
+ "host" => "myHost",
432
+ "foo" => "fancy",
433
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
434
+ "storageRW" => 51,
435
+ "bar" => "blahblah",
436
+ "blkio" => {
437
+ "write_ps" => 5,
438
+ "read_ps" => 2,
439
+ "total_ps" => 0
440
+ })
441
+ }
442
+
443
+ specify {
444
+ lines = result.split(/\n/).sort
445
+ expect(lines.length).to eq(4)
446
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
447
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.1 foo=fancy 0\.11 \d{10,}$/)
448
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
449
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
450
+ }
451
+
452
+ end # context
453
+
454
+ context "should hornor fields_exclude when fields_as_metrics (graphite)" do
455
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
456
+ let(:builder) {
457
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
458
+ "url" => "http://localhost/1234",
459
+ "fields_as_metrics" => true,
460
+ "metrics_format" => "graphite",
461
+ "fields_include" => ["cpu*"],
462
+ "fields_exclude" => [".*1"])
463
+ }
464
+ let(:event) { LogStash::Event.new(
465
+ "host" => "myHost",
466
+ "foo" => "fancy",
467
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
468
+ "storageRW" => 51,
469
+ "bar" => "blahblah",
470
+ "blkio" => {
471
+ "write_ps" => 5,
472
+ "read_ps" => 2,
473
+ "total_ps" => 0
474
+ })}
475
+
476
+ specify {
477
+ lines = result.split(/\n/).sort
478
+ expect(lines.length).to eq(3)
479
+ expect(lines.shift).to match(/^cpu\.0 0\.24 \d{10,}$/)
480
+ expect(lines.shift).to match(/^cpu\.2 0\.75 \d{10,}$/)
481
+ expect(lines.shift).to match(/^cpu\.3 0\.28 \d{10,}$/)
482
+ }
483
+
484
+ end # context
485
+
486
+ context "should hornor fields_exclude when fields_as_metrics (carbon2)" do
487
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
488
+ let(:builder) {
489
+ LogStash::Outputs::SumoLogic::PayloadBuilder.new(stats,
490
+ "url" => "http://localhost/1234",
491
+ "fields_as_metrics" => true,
492
+ "intrinsic_tags" => {
493
+ "host" => "%{host}"
494
+ },
495
+ "meta_tags" => {
496
+ "foo" => "%{foo}"
497
+ },
498
+ "fields_include" => ["cpu*"],
499
+ "fields_exclude" => [".*1"])
500
+ }
501
+ let(:event) { LogStash::Event.new(
502
+ "host" => "myHost",
503
+ "foo" => "fancy",
504
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
505
+ "storageRW" => 51,
506
+ "bar" => "blahblah",
507
+ "blkio" => {
508
+ "write_ps" => 5,
509
+ "read_ps" => 2,
510
+ "total_ps" => 0
511
+ })}
512
+
513
+ specify {
514
+ lines = result.split(/\n/).sort
515
+ expect(lines.length).to eq(3)
516
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
517
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
518
+ expect(lines.shift).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
519
+ }
520
+
521
+ end # context
522
+
523
+ end # describe