fluentd 0.14.2 → 0.14.5

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +77 -1131
  3. data/Rakefile +15 -0
  4. data/appveyor.yml +2 -2
  5. data/example/in_forward.conf +3 -0
  6. data/example/in_forward_client.conf +37 -0
  7. data/example/in_forward_shared_key.conf +15 -0
  8. data/example/in_forward_users.conf +24 -0
  9. data/example/multi_filters.conf +61 -0
  10. data/example/out_forward.conf +13 -13
  11. data/example/out_forward_client.conf +109 -0
  12. data/example/out_forward_shared_key.conf +36 -0
  13. data/example/out_forward_users.conf +65 -0
  14. data/example/{out_buffered_null.conf → out_null.conf} +10 -6
  15. data/example/secondary_file.conf +41 -0
  16. data/fluentd.gemspec +19 -16
  17. data/lib/fluent/agent.rb +5 -0
  18. data/lib/fluent/command/debug.rb +4 -4
  19. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +2 -0
  20. data/lib/fluent/compat/output.rb +5 -2
  21. data/lib/fluent/config/configure_proxy.rb +26 -5
  22. data/lib/fluent/config/error.rb +3 -0
  23. data/lib/fluent/config/section.rb +15 -0
  24. data/lib/fluent/event_router.rb +77 -4
  25. data/lib/fluent/plugin/base.rb +12 -3
  26. data/lib/fluent/plugin/buffer.rb +5 -1
  27. data/lib/fluent/plugin/filter.rb +48 -6
  28. data/lib/fluent/plugin/filter_record_transformer.rb +3 -1
  29. data/lib/fluent/plugin/filter_stdout.rb +0 -4
  30. data/lib/fluent/plugin/in_debug_agent.rb +5 -5
  31. data/lib/fluent/plugin/in_dummy.rb +9 -1
  32. data/lib/fluent/plugin/in_forward.rb +330 -62
  33. data/lib/fluent/plugin/in_monitor_agent.rb +31 -77
  34. data/lib/fluent/plugin/in_tail.rb +76 -92
  35. data/lib/fluent/plugin/multi_output.rb +4 -0
  36. data/lib/fluent/plugin/out_forward.rb +328 -222
  37. data/lib/fluent/plugin/out_null.rb +37 -0
  38. data/lib/fluent/plugin/out_secondary_file.rb +128 -0
  39. data/lib/fluent/plugin/out_stdout.rb +38 -2
  40. data/lib/fluent/plugin/output.rb +29 -6
  41. data/lib/fluent/plugin/storage_local.rb +16 -0
  42. data/lib/fluent/plugin_helper/timer.rb +6 -1
  43. data/lib/fluent/root_agent.rb +4 -1
  44. data/lib/fluent/supervisor.rb +62 -9
  45. data/lib/fluent/test/base.rb +3 -0
  46. data/lib/fluent/test/driver/base.rb +5 -0
  47. data/lib/fluent/test/formatter_test.rb +2 -0
  48. data/lib/fluent/test/parser_test.rb +2 -0
  49. data/lib/fluent/test/startup_shutdown.rb +33 -0
  50. data/lib/fluent/version.rb +1 -1
  51. data/lib/fluent/winsvc.rb +1 -2
  52. data/test/compat/test_calls_super.rb +2 -0
  53. data/test/config/test_configurable.rb +88 -0
  54. data/test/config/test_types.rb +7 -3
  55. data/test/plugin/test_filter.rb +121 -23
  56. data/test/plugin/test_filter_record_transformer.rb +22 -6
  57. data/test/plugin/test_in_debug_agent.rb +2 -2
  58. data/test/plugin/test_in_forward.rb +920 -407
  59. data/test/plugin/test_in_monitor_agent.rb +333 -0
  60. data/test/plugin/test_in_tail.rb +686 -595
  61. data/test/plugin/test_out_forward.rb +150 -207
  62. data/test/plugin/test_out_null.rb +85 -9
  63. data/test/plugin/test_out_secondary_file.rb +432 -0
  64. data/test/plugin/test_out_stdout.rb +143 -45
  65. data/test/plugin/test_output.rb +53 -0
  66. data/test/plugin/test_output_as_buffered.rb +13 -0
  67. data/test/plugin/test_output_as_buffered_overflow.rb +3 -0
  68. data/test/plugin/test_output_as_buffered_retries.rb +11 -0
  69. data/test/plugin/test_output_as_buffered_secondary.rb +12 -0
  70. data/test/plugin/test_output_as_standard.rb +12 -0
  71. data/test/plugin_helper/test_compat_parameters.rb +2 -0
  72. data/test/plugin_helper/test_timer.rb +31 -0
  73. data/test/test_event_router.rb +87 -0
  74. data/test/test_filter.rb +48 -6
  75. data/test/test_log.rb +5 -2
  76. data/test/test_output.rb +41 -1
  77. data/test/test_plugin_classes.rb +17 -9
  78. data/test/test_root_agent.rb +188 -0
  79. metadata +62 -68
  80. data/lib/fluent/plugin/out_buffered_null.rb +0 -59
  81. data/lib/fluent/plugin/out_buffered_stdout.rb +0 -70
  82. data/test/plugin/test_out_buffered_null.rb +0 -79
  83. data/test/plugin/test_out_buffered_stdout.rb +0 -122
@@ -1,14 +1,17 @@
1
1
  require_relative '../helper'
2
2
  require 'fluent/test'
3
+ require 'fluent/test/startup_shutdown'
3
4
  require 'fluent/plugin/out_forward'
4
5
 
5
6
  class ForwardOutputTest < Test::Unit::TestCase
7
+ extend Fluent::Test::StartupShutdown
8
+
6
9
  def setup
7
10
  Fluent::Test.setup
8
11
  end
9
12
 
10
13
  TARGET_HOST = '127.0.0.1'
11
- TARGET_PORT = 13999
14
+ TARGET_PORT = unused_port
12
15
  CONFIG = %[
13
16
  send_timeout 51
14
17
  heartbeat_type udp
@@ -25,7 +28,7 @@ class ForwardOutputTest < Test::Unit::TestCase
25
28
  ]
26
29
 
27
30
  def create_driver(conf=CONFIG)
28
- Fluent::Test::BufferedOutputTestDriver.new(Fluent::ForwardOutput) {
31
+ d = Fluent::Test::BufferedOutputTestDriver.new(Fluent::ForwardOutput) {
29
32
  attr_reader :responses, :exceptions
30
33
 
31
34
  def initialize
@@ -34,18 +37,32 @@ class ForwardOutputTest < Test::Unit::TestCase
34
37
  @exceptions = []
35
38
  end
36
39
 
37
- def send_data(node, tag, chunk)
38
- # Original #send_data returns nil when it does not wait for responses or when on response timeout.
39
- @responses << super(node, tag, chunk)
40
- rescue => e
41
- @exceptions << e
42
- raise e
40
+ def configure(conf)
41
+ super
42
+ m = Module.new do
43
+ def send_data(tag, chunk)
44
+ @sender.responses << super
45
+ rescue => e
46
+ @sender.exceptions << e
47
+ raise e
48
+ end
49
+ end
50
+ @nodes.each do |node|
51
+ node.singleton_class.prepend(m)
52
+ end
43
53
  end
44
54
  }.configure(conf)
55
+ router = Object.new
56
+ def router.method_missing(name, *args, **kw_args, &block)
57
+ Engine.root_agent.event_router.__send__(name, *args, **kw_args, &block)
58
+ end
59
+ d.instance.router = router
60
+ d
45
61
  end
46
62
 
47
63
  def test_configure
48
64
  d = create_driver(%[
65
+ self_hostname localhost
49
66
  <server>
50
67
  name test
51
68
  host #{TARGET_HOST}
@@ -59,7 +76,7 @@ class ForwardOutputTest < Test::Unit::TestCase
59
76
  node = nodes.first
60
77
  assert_equal "test", node.name
61
78
  assert_equal '127.0.0.1', node.host
62
- assert_equal 13999, node.port
79
+ assert_equal TARGET_PORT, node.port
63
80
  end
64
81
 
65
82
  def test_configure_udp_heartbeat
@@ -79,11 +96,9 @@ class ForwardOutputTest < Test::Unit::TestCase
79
96
 
80
97
  d = create_driver(CONFIG + "\nheartbeat_type tcp\ndns_round_robin true")
81
98
  assert_equal true, d.instance.dns_round_robin
82
- assert_equal true, d.instance.nodes.first.conf.dns_round_robin
83
99
 
84
100
  d = create_driver(CONFIG + "\nheartbeat_type none\ndns_round_robin true")
85
101
  assert_equal true, d.instance.dns_round_robin
86
- assert_equal true, d.instance.nodes.first.conf.dns_round_robin
87
102
  end
88
103
 
89
104
  def test_configure_no_server
@@ -118,70 +133,6 @@ class ForwardOutputTest < Test::Unit::TestCase
118
133
  assert_equal 2, d.instance.ack_response_timeout
119
134
  end
120
135
 
121
- def test_sending_contains_with_ack
122
- target_input_driver = create_target_input_driver(true)
123
-
124
- d = create_driver(CONFIG + %[
125
- ack_response_timeout 1s
126
- ])
127
-
128
- time = Time.parse("2011-01-02 13:14:15 UTC").to_i
129
-
130
- records = [
131
- {"a" => 1},
132
- {"a" => 2}
133
- ]
134
- d.register_run_post_condition do
135
- d.instance.responses.length == 1
136
- end
137
-
138
- target_input_driver.run do
139
- d.run do
140
- records.each do |record|
141
- d.emit record, time
142
- end
143
- end
144
- end
145
-
146
- emits = target_input_driver.emits
147
- assert_equal ['test', time, records[0]], emits[0]
148
- assert_equal ['test', time, records[1]], emits[1]
149
-
150
- assert_equal target_input_driver.instance.received_options[0]['size'], 2
151
- end
152
-
153
- def test_sending_contains_without_ack
154
- target_input_driver = create_target_input_driver(true)
155
-
156
- d = create_driver(CONFIG + %[
157
- ack_response_timeout 1s
158
- ])
159
-
160
- time = Time.parse("2011-01-02 13:14:15 UTC").to_i
161
-
162
- records = [
163
- {"a" => 1},
164
- {"a" => 2}
165
- ]
166
- d.register_run_post_condition do
167
- d.instance.responses.length == 1
168
- end
169
-
170
- target_input_driver.run do
171
- d.run do
172
- records.each do |record|
173
- d.emit record, time
174
- end
175
- end
176
- end
177
-
178
- emits = target_input_driver.emits
179
- assert_equal ['test', time, records[0]], emits[0]
180
- assert_equal ['test', time, records[1]], emits[1]
181
-
182
- assert_equal target_input_driver.instance.received_options[0]['size'], 2
183
- end
184
-
185
136
  def test_send_with_time_as_integer
186
137
  target_input_driver = create_target_input_driver
187
138
 
@@ -252,7 +203,7 @@ class ForwardOutputTest < Test::Unit::TestCase
252
203
  end
253
204
 
254
205
  def test_send_to_a_node_supporting_responses
255
- target_input_driver = create_target_input_driver(true)
206
+ target_input_driver = create_target_input_driver(response_stub: true)
256
207
 
257
208
  d = create_driver(CONFIG + %[flush_interval 1s])
258
209
 
@@ -314,7 +265,7 @@ class ForwardOutputTest < Test::Unit::TestCase
314
265
  end
315
266
 
316
267
  def test_require_a_node_supporting_responses_to_respond_with_ack
317
- target_input_driver = create_target_input_driver(true)
268
+ target_input_driver = create_target_input_driver
318
269
 
319
270
  d = create_driver(CONFIG + %[
320
271
  flush_interval 1s
@@ -350,8 +301,7 @@ class ForwardOutputTest < Test::Unit::TestCase
350
301
  end
351
302
 
352
303
  def test_require_a_node_not_supporting_responses_to_respond_with_ack
353
- # in_forward, that doesn't support ack feature, and keep connection alive
354
- target_input_driver = create_target_input_driver
304
+ target_input_driver = create_target_input_driver(response_stub: ->(_option) { nil }, disconnect: true)
355
305
 
356
306
  d = create_driver(CONFIG + %[
357
307
  flush_interval 1s
@@ -394,7 +344,7 @@ class ForwardOutputTest < Test::Unit::TestCase
394
344
  # bdf1f4f104c00a791aa94dc20087fe2011e1fd83
395
345
  def test_require_a_node_not_supporting_responses_2_to_respond_with_ack
396
346
  # in_forward, that doesn't support ack feature, and disconnect immediately
397
- target_input_driver = create_target_input_driver(false, true)
347
+ target_input_driver = create_target_input_driver(response_stub: ->(_option) { nil }, disconnect: true)
398
348
 
399
349
  d = create_driver(CONFIG + %[
400
350
  flush_interval 1s
@@ -413,7 +363,7 @@ class ForwardOutputTest < Test::Unit::TestCase
413
363
  end
414
364
  d.run_timeout = 2
415
365
 
416
- assert_raise Fluent::ForwardOutputConnectionClosedError do
366
+ assert_raise Fluent::ForwardOutputACKTimeoutError do
417
367
  target_input_driver.run do
418
368
  d.run do
419
369
  records.each do |record|
@@ -434,84 +384,136 @@ class ForwardOutputTest < Test::Unit::TestCase
434
384
  assert_equal false, node.available # node is regarded as unavailable when unexpected EOF
435
385
  end
436
386
 
437
- def create_target_input_driver(do_respond=false, disconnect=false, conf=TARGET_CONFIG)
438
- require 'fluent/plugin/in_forward'
387
+ def test_authentication_with_shared_key
388
+ input_conf = TARGET_CONFIG + %[
389
+ <security>
390
+ self_hostname in.localhost
391
+ shared_key fluentd-sharedkey
392
+ <client>
393
+ host 127.0.0.1
394
+ </client>
395
+ </security>
396
+ ]
397
+ target_input_driver = create_target_input_driver(conf: input_conf)
398
+
399
+ output_conf = %[
400
+ send_timeout 51
401
+ <security>
402
+ self_hostname localhost
403
+ shared_key fluentd-sharedkey
404
+ </security>
405
+ <server>
406
+ name test
407
+ host #{TARGET_HOST}
408
+ port #{TARGET_PORT}
409
+ shared_key fluentd-sharedkey
410
+ </server>
411
+ ]
412
+ d = create_driver(output_conf)
439
413
 
440
- # TODO: Support actual TCP heartbeat test
441
- DummyEngineDriver.new(Fluent::ForwardInput) {
442
- handler_class = Class.new(Fluent::ForwardInput::Handler) { |klass|
443
- attr_reader :chunk_counter # for checking if received data is successfully deserialized
444
- attr_reader :received_options
445
-
446
- def initialize(sock, log, on_message)
447
- @sock = sock
448
- @log = log
449
- @chunk_counter = 0
450
- @received_options = []
451
- @on_message = ->(msg, chunk_size, source) {
452
- option = on_message.call(msg, chunk_size, source)
453
- @received_options << option
454
- option
455
- }
456
- @source = nil
414
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
415
+ records = [
416
+ {"a" => 1},
417
+ {"a" => 2}
418
+ ]
419
+
420
+ target_input_driver.run do
421
+ sleep 0.1 until target_input_driver.instance.instance_eval{ @thread } && target_input_driver.instance.instance_eval{ @thread }.status
422
+
423
+ d.run do
424
+ records.each do |record|
425
+ d.emit(record, time)
457
426
  end
458
427
 
459
- if do_respond
460
- def write(data)
461
- @sock.write data
462
- rescue
463
- @sock.close_write
464
- @sock.close
465
- end
466
- else
467
- def write(data)
468
- # do nothing
469
- end
428
+ # run_post_condition of Fluent::Test::*Driver are buggy:
429
+ t = Time.now
430
+ while Time.now < t + 15 && target_input_driver.emits.size < 2
431
+ sleep 0.1
470
432
  end
433
+ end
434
+ end
471
435
 
472
- def close
473
- unless @sock.closed?
474
- @sock.close_write
475
- @sock.close
476
- end
436
+ emits = target_input_driver.emits
437
+ assert{ emits != [] }
438
+ assert_equal(['test', time, records[0]], emits[0])
439
+ assert_equal(['test', time, records[1]], emits[1])
440
+ end
441
+
442
+ def test_authentication_with_user_auth
443
+ input_conf = TARGET_CONFIG + %[
444
+ <security>
445
+ self_hostname in.localhost
446
+ shared_key fluentd-sharedkey
447
+ user_auth true
448
+ <user>
449
+ username fluentd
450
+ password fluentd
451
+ </user>
452
+ <client>
453
+ host 127.0.0.1
454
+ </client>
455
+ </security>
456
+ ]
457
+ target_input_driver = create_target_input_driver(conf: input_conf)
458
+
459
+ output_conf = %[
460
+ send_timeout 51
461
+ <security>
462
+ self_hostname localhost
463
+ shared_key fluentd-sharedkey
464
+ </security>
465
+ <server>
466
+ name test
467
+ host #{TARGET_HOST}
468
+ port #{TARGET_PORT}
469
+ shared_key fluentd-sharedkey
470
+ username fluentd
471
+ password fluentd
472
+ </server>
473
+ ]
474
+ d = create_driver(output_conf)
475
+
476
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
477
+ records = [
478
+ {"a" => 1},
479
+ {"a" => 2}
480
+ ]
481
+
482
+ target_input_driver.run do
483
+ sleep 0.1 until target_input_driver.instance.instance_eval{ @thread } && target_input_driver.instance.instance_eval{ @thread }.status
484
+
485
+ d.run do
486
+ records.each do |record|
487
+ d.emit(record, time)
477
488
  end
478
- }
479
-
480
- define_method(:_start) do
481
- @thread = Thread.new do
482
- Socket.tcp_server_loop(@bind, @port) do |sock, client_addrinfo|
483
- begin
484
- handler = handler_class.new(sock, @log, method(:on_message))
485
- loop do
486
- raw_data = sock.recv(1024)
487
- handler.on_read(raw_data)
488
- # chunk_counter is reset to zero only after all the data have been received and successfully deserialized.
489
- break if handler.chunk_counter == 0
490
- break if sock.closed?
491
- end
492
- if disconnect
493
- handler.close
494
- sock = nil
495
- end
496
- sleep # wait for connection to be closed by client
497
- ensure
498
- if sock && !sock.closed?
499
- sock.close_write
500
- sock.close
501
- end
502
- @received_options = handler.received_options
503
- end
504
- end
489
+
490
+ # run_post_condition of Fluent::Test::*Driver are buggy:
491
+ t = Time.now
492
+ while Time.now < t + 15 && target_input_driver.emits.size < 2
493
+ sleep 0.1
505
494
  end
506
495
  end
496
+ end
507
497
 
508
- attr_reader :received_options
498
+ emits = target_input_driver.emits
499
+ assert{ emits != [] }
500
+ assert_equal(['test', time, records[0]], emits[0])
501
+ assert_equal(['test', time, records[1]], emits[1])
502
+ end
503
+
504
+ def create_target_input_driver(response_stub: nil, disconnect: false, conf: TARGET_CONFIG)
505
+ require 'fluent/plugin/in_forward'
509
506
 
510
- def _shutdown
511
- @thread.kill
512
- @thread.join
507
+ # TODO: Support actual TCP heartbeat test
508
+ Fluent::Test::InputTestDriver.new(Fluent::ForwardInput) {
509
+ if response_stub.nil?
510
+ # do nothing because in_forward responds for ack option in default
511
+ else
512
+ define_method(:response) do |options|
513
+ return response_stub.(options)
514
+ end
513
515
  end
514
- }.configure(conf).inject_router()
516
+ }.configure(conf)
515
517
  end
516
518
 
517
519
  def test_heartbeat_type_none
@@ -527,63 +529,4 @@ class ForwardOutputTest < Test::Unit::TestCase
527
529
  node.tick
528
530
  assert_equal node.available, true
529
531
  end
530
-
531
- # To suppress calling `ForwardInput#start` in `DummyEngineDriver`,
532
- # `DummyEnigneDriver` should avoid calling CallSuperMixin.prepend at `Fluent::Compat::Input#initialize`.
533
- module SuppressCallSuperMixin
534
- def start
535
- _start
536
- end
537
-
538
- def before_shutdown
539
- # nothing
540
- end
541
-
542
- def shutdown
543
- _shutdown
544
- end
545
- end
546
-
547
- class DummyEngineDriver < Fluent::Test::TestDriver
548
- def initialize(klass, &block)
549
- super(klass, &block)
550
- @instance.class.prepend(SuppressCallSuperMixin)
551
- @engine = DummyEngineClass.new
552
- end
553
-
554
- def inject_router
555
- @instance.router = @engine
556
- self
557
- end
558
-
559
- def run(&block)
560
- super(&block)
561
- end
562
-
563
- def emits
564
- all = []
565
- @engine.emit_streams.each {|tag,events|
566
- events.each {|time,record|
567
- all << [tag, time, record]
568
- }
569
- }
570
- all
571
- end
572
-
573
- class DummyEngineClass
574
- attr_reader :emit_streams
575
-
576
- def initialize
577
- @emit_streams ||= []
578
- end
579
-
580
- def clear!
581
- @emit_streams = []
582
- end
583
-
584
- def emit_stream(tag, es)
585
- @emit_streams << [tag, es.to_a]
586
- end
587
- end
588
- end
589
532
  end
@@ -11,19 +11,95 @@ class NullOutputTest < Test::Unit::TestCase
11
11
  Fluent::Test::Driver::Output.new(Fluent::Plugin::NullOutput).configure(conf)
12
12
  end
13
13
 
14
- def test_configure
15
- assert_nothing_raised do
16
- create_driver
14
+ sub_test_case 'non-buffered' do
15
+ test 'configure' do
16
+ assert_nothing_raised do
17
+ create_driver
18
+ end
19
+ end
20
+
21
+ test 'process' do
22
+ d = create_driver
23
+ assert_nothing_raised do
24
+ d.run do
25
+ d.feed("test", Fluent::EventTime.now, {"test" => "null"})
26
+ end
27
+ end
28
+ assert_equal([], d.events(tag: "test"))
17
29
  end
18
30
  end
19
31
 
20
- def test_process
21
- d = create_driver
22
- assert_nothing_raised do
23
- d.run do
24
- d.feed("test", Fluent::EventTime.now, {"test" => "null"})
32
+ sub_test_case 'buffered' do
33
+ test 'default chunk limit size is 100' do
34
+ d = create_driver(config_element("ROOT", "", {}, [config_element("buffer")]))
35
+ assert_equal 10 * 1024, d.instance.buffer_config.chunk_limit_size
36
+ assert d.instance.buffer_config.flush_at_shutdown
37
+ assert_equal ['tag'], d.instance.buffer_config.chunk_keys
38
+ assert d.instance.chunk_key_tag
39
+ assert !d.instance.chunk_key_time
40
+ assert_equal [], d.instance.chunk_keys
41
+ end
42
+
43
+ test 'writes standard formattted chunks' do
44
+ d = create_driver(config_element("ROOT", "", {}, [config_element("buffer")]))
45
+ t = event_time("2016-05-23 00:22:13 -0800")
46
+ d.run(default_tag: 'test', flush: true) do
47
+ d.feed(t, {"message" => "null null null"})
48
+ d.feed(t, {"message" => "null null"})
49
+ d.feed(t, {"message" => "null"})
25
50
  end
51
+
52
+ assert_equal 3, d.instance.emit_count
53
+ assert_equal 3, d.instance.emit_records
54
+ end
55
+
56
+ test 'check for chunk passed to #write' do
57
+ d = create_driver(config_element("ROOT", "", {}, [config_element("buffer")]))
58
+ data = []
59
+ d.instance.feed_proc = ->(chunk){ data << [chunk.unique_id, chunk.metadata.tag, chunk.read] }
60
+
61
+ t = event_time("2016-05-23 00:22:13 -0800")
62
+ d.run(default_tag: 'test', flush: true) do
63
+ d.feed(t, {"message" => "null null null"})
64
+ d.feed(t, {"message" => "null null"})
65
+ d.feed(t, {"message" => "null"})
66
+ end
67
+
68
+ assert_equal 1, data.size
69
+ _, tag, binary = data.first
70
+ events = []
71
+ Fluent::MessagePackFactory.unpacker.feed_each(binary){|obj| events << obj }
72
+ assert_equal 'test', tag
73
+ assert_equal [ [t, {"message" => "null null null"}], [t, {"message" => "null null"}], [t, {"message" => "null"}] ], events
74
+ end
75
+
76
+ test 'check for chunk passed to #try_write' do
77
+ d = create_driver(config_element("ROOT", "", {}, [config_element("buffer")]))
78
+ data = []
79
+ d.instance.feed_proc = ->(chunk){ data << [chunk.unique_id, chunk.metadata.tag, chunk.read] }
80
+ d.instance.delayed = true
81
+
82
+ t = event_time("2016-05-23 00:22:13 -0800")
83
+ d.run(default_tag: 'test', flush: true, shutdown: false) do
84
+ d.feed(t, {"message" => "null null null"})
85
+ d.feed(t, {"message" => "null null"})
86
+ d.feed(t, {"message" => "null"})
87
+ end
88
+
89
+ assert_equal 1, data.size
90
+ chunk_id, tag, binary = data.first
91
+ events = []
92
+ Fluent::MessagePackFactory.unpacker.feed_each(binary){|obj| events << obj }
93
+ assert_equal 'test', tag
94
+ assert_equal [ [t, {"message" => "null null null"}], [t, {"message" => "null null"}], [t, {"message" => "null"}] ], events
95
+
96
+ assert_equal [chunk_id], d.instance.buffer.dequeued.keys
97
+
98
+ d.instance.commit_write(chunk_id)
99
+
100
+ assert_equal [], d.instance.buffer.dequeued.keys
101
+
102
+ d.instance_shutdown
26
103
  end
27
- assert_equal([], d.events(tag: "test"))
28
104
  end
29
105
  end