fluentd 0.14.11-x86-mingw32 → 0.14.12-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -5
  3. data/ChangeLog +54 -2
  4. data/example/in_dummy_blocks.conf +17 -0
  5. data/example/in_forward_tls.conf +14 -0
  6. data/example/in_forward_workers.conf +21 -0
  7. data/example/logevents.conf +25 -0
  8. data/example/out_forward_heartbeat_none.conf +16 -0
  9. data/example/out_forward_tls.conf +18 -0
  10. data/example/suppress_config_dump.conf +7 -0
  11. data/lib/fluent/agent.rb +3 -32
  12. data/lib/fluent/clock.rb +62 -0
  13. data/lib/fluent/command/fluentd.rb +12 -0
  14. data/lib/fluent/compat/input.rb +10 -1
  15. data/lib/fluent/compat/output.rb +40 -1
  16. data/lib/fluent/config/configure_proxy.rb +30 -7
  17. data/lib/fluent/config/section.rb +4 -0
  18. data/lib/fluent/config/types.rb +2 -2
  19. data/lib/fluent/configurable.rb +31 -5
  20. data/lib/fluent/engine.rb +61 -12
  21. data/lib/fluent/event_router.rb +6 -0
  22. data/lib/fluent/load.rb +0 -1
  23. data/lib/fluent/log.rb +118 -42
  24. data/lib/fluent/match.rb +37 -0
  25. data/lib/fluent/plugin.rb +25 -3
  26. data/lib/fluent/plugin/base.rb +4 -0
  27. data/lib/fluent/plugin/buf_file.rb +38 -14
  28. data/lib/fluent/plugin/buffer.rb +20 -20
  29. data/lib/fluent/plugin/buffer/file_chunk.rb +2 -2
  30. data/lib/fluent/plugin/compressable.rb +1 -0
  31. data/lib/fluent/plugin/filter_record_transformer.rb +3 -6
  32. data/lib/fluent/plugin/formatter_csv.rb +4 -1
  33. data/lib/fluent/plugin/formatter_hash.rb +5 -1
  34. data/lib/fluent/plugin/formatter_json.rb +10 -0
  35. data/lib/fluent/plugin/formatter_ltsv.rb +2 -1
  36. data/lib/fluent/plugin/in_dummy.rb +4 -0
  37. data/lib/fluent/plugin/in_exec.rb +4 -0
  38. data/lib/fluent/plugin/in_forward.rb +11 -3
  39. data/lib/fluent/plugin/in_gc_stat.rb +4 -0
  40. data/lib/fluent/plugin/in_http.rb +4 -0
  41. data/lib/fluent/plugin/in_monitor_agent.rb +29 -2
  42. data/lib/fluent/plugin/in_object_space.rb +4 -1
  43. data/lib/fluent/plugin/in_syslog.rb +4 -0
  44. data/lib/fluent/plugin/in_tail.rb +193 -116
  45. data/lib/fluent/plugin/in_tcp.rb +5 -1
  46. data/lib/fluent/plugin/in_udp.rb +4 -0
  47. data/lib/fluent/plugin/input.rb +4 -0
  48. data/lib/fluent/plugin/out_copy.rb +4 -0
  49. data/lib/fluent/plugin/out_exec.rb +4 -0
  50. data/lib/fluent/plugin/out_exec_filter.rb +4 -0
  51. data/lib/fluent/plugin/out_file.rb +70 -30
  52. data/lib/fluent/plugin/out_forward.rb +132 -28
  53. data/lib/fluent/plugin/out_null.rb +10 -0
  54. data/lib/fluent/plugin/out_relabel.rb +4 -0
  55. data/lib/fluent/plugin/out_roundrobin.rb +4 -0
  56. data/lib/fluent/plugin/out_secondary_file.rb +5 -0
  57. data/lib/fluent/plugin/out_stdout.rb +5 -0
  58. data/lib/fluent/plugin/output.rb +18 -9
  59. data/lib/fluent/plugin/storage_local.rb +25 -2
  60. data/lib/fluent/plugin_helper/cert_option.rb +159 -0
  61. data/lib/fluent/plugin_helper/child_process.rb +6 -6
  62. data/lib/fluent/plugin_helper/compat_parameters.rb +1 -1
  63. data/lib/fluent/plugin_helper/event_loop.rb +29 -4
  64. data/lib/fluent/plugin_helper/inject.rb +14 -1
  65. data/lib/fluent/plugin_helper/server.rb +275 -31
  66. data/lib/fluent/plugin_helper/socket.rb +144 -4
  67. data/lib/fluent/plugin_helper/socket_option.rb +2 -17
  68. data/lib/fluent/plugin_helper/storage.rb +7 -1
  69. data/lib/fluent/plugin_helper/thread.rb +16 -4
  70. data/lib/fluent/registry.rb +26 -9
  71. data/lib/fluent/root_agent.rb +7 -3
  72. data/lib/fluent/supervisor.rb +37 -15
  73. data/lib/fluent/system_config.rb +37 -10
  74. data/lib/fluent/test.rb +2 -0
  75. data/lib/fluent/test/driver/base.rb +24 -26
  76. data/lib/fluent/test/helpers.rb +21 -0
  77. data/lib/fluent/version.rb +1 -1
  78. data/test/command/test_fluentd.rb +274 -4
  79. data/test/config/test_configurable.rb +154 -0
  80. data/test/config/test_configure_proxy.rb +180 -1
  81. data/test/config/test_system_config.rb +10 -0
  82. data/test/config/test_types.rb +1 -0
  83. data/test/plugin/test_base.rb +4 -0
  84. data/test/plugin/test_buf_file.rb +241 -9
  85. data/test/plugin/test_buffer.rb +11 -11
  86. data/test/plugin/test_buffer_file_chunk.rb +6 -6
  87. data/test/plugin/test_compressable.rb +3 -0
  88. data/test/plugin/test_filter.rb +4 -0
  89. data/test/plugin/test_filter_record_transformer.rb +20 -0
  90. data/test/plugin/test_formatter_csv.rb +9 -0
  91. data/test/plugin/test_formatter_hash.rb +35 -0
  92. data/test/plugin/test_formatter_json.rb +8 -0
  93. data/test/plugin/test_formatter_ltsv.rb +7 -0
  94. data/test/plugin/test_in_dummy.rb +7 -3
  95. data/test/plugin/test_in_monitor_agent.rb +43 -5
  96. data/test/plugin/test_in_tail.rb +97 -4
  97. data/test/plugin/test_input.rb +4 -0
  98. data/test/plugin/test_out_file.rb +46 -7
  99. data/test/plugin/test_out_forward.rb +59 -7
  100. data/test/plugin/test_output.rb +10 -4
  101. data/test/plugin/test_output_as_buffered.rb +37 -25
  102. data/test/plugin/test_output_as_buffered_compress.rb +1 -1
  103. data/test/plugin/test_output_as_buffered_retries.rb +6 -6
  104. data/test/plugin/test_output_as_buffered_secondary.rb +91 -31
  105. data/test/plugin/test_storage_local.rb +40 -1
  106. data/test/plugin_helper/test_child_process.rb +29 -28
  107. data/test/plugin_helper/test_compat_parameters.rb +1 -1
  108. data/test/plugin_helper/test_inject.rb +27 -9
  109. data/test/plugin_helper/test_server.rb +822 -50
  110. data/test/plugin_helper/test_storage.rb +11 -0
  111. data/test/plugin_helper/test_timer.rb +1 -0
  112. data/test/test_clock.rb +164 -0
  113. data/test/test_log.rb +146 -15
  114. data/test/test_plugin.rb +251 -0
  115. data/test/test_supervisor.rb +65 -57
  116. data/test/test_test_drivers.rb +2 -2
  117. metadata +18 -7
  118. data/lib/fluent/process.rb +0 -504
  119. data/test/test_process.rb +0 -48
@@ -135,6 +135,17 @@ class StorageHelperTest < Test::Unit::TestCase
135
135
  end
136
136
  end
137
137
 
138
+ test 'raises config error if config argument has invalid characters' do
139
+ d = Dummy.new
140
+ assert_raise Fluent::ConfigError.new("Argument in <storage ARG> uses invalid characters: 'yaa y'") do
141
+ d.configure(config_element('root', '', {}, [config_element('storage', 'yaa y', {'@type' => 'local'})]))
142
+ end
143
+ d.configure(config_element())
144
+ assert_raise Fluent::ConfigError.new("Argument in <storage ARG> uses invalid characters: 'a,b'") do
145
+ d.storage_create(usage: 'a,b', type: 'local')
146
+ end
147
+ end
148
+
138
149
  test 'can be configured without storage sections' do
139
150
  d = Dummy.new
140
151
  assert_nothing_raised do
@@ -122,6 +122,7 @@ class TimerTest < Test::Unit::TestCase
122
122
  sleep(0.1) while waiting_timer
123
123
 
124
124
  assert_equal(1, counter)
125
+ waiting(4){ sleep 0.1 while watchers.first.attached? }
125
126
  assert_false(watchers.first.attached?)
126
127
  watchers = d1._event_loop.watchers.reject {|w| w.is_a?(Fluent::PluginHelper::EventLoop::DefaultWatcher) }
127
128
  assert_equal(0, watchers.size)
@@ -0,0 +1,164 @@
1
+ require_relative 'helper'
2
+ require 'fluent/clock'
3
+
4
+ require 'timecop'
5
+
6
+ class ClockTest < ::Test::Unit::TestCase
7
+ teardown do
8
+ Fluent::Clock.return # call it always not to affect other tests
9
+ end
10
+
11
+ sub_test_case 'without any pre-operation' do
12
+ test 'clock can provides incremental floating point number based on second' do
13
+ c1 = Fluent::Clock.now
14
+ assert_kind_of Float, c1
15
+ sleep 1.1
16
+ c2 = Fluent::Clock.now
17
+ assert{ c2 >= c1 + 1.0 && c2 < c1 + 9.0 } # if clock returns deci-second (fantastic!), c2 should be larger than c1 + 10
18
+ end
19
+
20
+ test 'clock value will proceed even if timecop freezes Time' do
21
+ Timecop.freeze(Time.now) do
22
+ c1 = Fluent::Clock.now
23
+ assert_kind_of Float, c1
24
+ sleep 1.1
25
+ c2 = Fluent::Clock.now
26
+ assert{ c2 >= c1 + 1.0 && c2 < c1 + 9.0 }
27
+ end
28
+ end
29
+ end
30
+
31
+ sub_test_case 'using #freeze without any arguments' do
32
+ test 'Clock.freeze without arguments freezes clock with current clock value' do
33
+ c0 = Fluent::Clock.now
34
+ Fluent::Clock.freeze
35
+ c1 = Fluent::Clock.now
36
+ Fluent::Clock.return
37
+ c2 = Fluent::Clock.now
38
+ assert{ c0 <= c1 && c1 <= c2 }
39
+ end
40
+
41
+ test 'Clock.return raises an error if it is called in block' do
42
+ assert_raise RuntimeError.new("invalid return while running code in blocks") do
43
+ Fluent::Clock.freeze do
44
+ Fluent::Clock.return
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ sub_test_case 'using #freeze with clock value' do
51
+ test 'Clock.now always returns frozen time until #return called' do
52
+ c0 = Fluent::Clock.now
53
+ Fluent::Clock.freeze(c0)
54
+ assert_equal c0, Fluent::Clock.now
55
+ sleep 0.5
56
+ assert_equal c0, Fluent::Clock.now
57
+ sleep 0.6
58
+ assert_equal c0, Fluent::Clock.now
59
+
60
+ Fluent::Clock.return
61
+ c1 = Fluent::Clock.now
62
+ assert{ c1 >= c0 + 1.0 }
63
+ end
64
+
65
+ test 'Clock.now returns frozen time in the block argument of #freeze' do
66
+ c0 = Fluent::Clock.now
67
+ Fluent::Clock.freeze(c0) do
68
+ assert_equal c0, Fluent::Clock.now
69
+ sleep 0.5
70
+ assert_equal c0, Fluent::Clock.now
71
+ sleep 0.6
72
+ assert_equal c0, Fluent::Clock.now
73
+ end
74
+ c1 = Fluent::Clock.now
75
+ assert{ c1 >= c0 + 1.0 }
76
+ end
77
+
78
+ test 'Clock.now returns unfrozen value after jumping out from block by raising errors' do
79
+ c0 = Fluent::Clock.now
80
+ rescued_error = nil
81
+ begin
82
+ Fluent::Clock.freeze(c0) do
83
+ assert_equal c0, Fluent::Clock.now
84
+ sleep 0.5
85
+ assert_equal c0, Fluent::Clock.now
86
+ sleep 0.6
87
+ assert_equal c0, Fluent::Clock.now
88
+ raise "bye!"
89
+ end
90
+ rescue => e
91
+ rescued_error = e
92
+ end
93
+ assert rescued_error # ensure to rescue an error
94
+ c1 = Fluent::Clock.now
95
+ assert{ c1 >= c0 + 1.0 }
96
+ end
97
+
98
+ test 'Clock.return cancels all Clock.freeze effects by just once' do
99
+ c0 = Fluent::Clock.now
100
+ sleep 0.1
101
+ c1 = Fluent::Clock.now
102
+ sleep 0.1
103
+ c2 = Fluent::Clock.now
104
+ Fluent::Clock.freeze(c0)
105
+ sleep 0.1
106
+ assert_equal c0, Fluent::Clock.now
107
+ Fluent::Clock.freeze(c1)
108
+ sleep 0.1
109
+ assert_equal c1, Fluent::Clock.now
110
+ Fluent::Clock.freeze(c2)
111
+ sleep 0.1
112
+ assert_equal c2, Fluent::Clock.now
113
+
114
+ Fluent::Clock.return
115
+ assert{ Fluent::Clock.now > c2 }
116
+ end
117
+
118
+ test 'Clock.freeze allows nested blocks by itself' do
119
+ c0 = Fluent::Clock.now
120
+ sleep 0.1
121
+ c1 = Fluent::Clock.now
122
+ sleep 0.1
123
+ c2 = Fluent::Clock.now
124
+ Fluent::Clock.freeze(c0) do
125
+ sleep 0.1
126
+ assert_equal c0, Fluent::Clock.now
127
+ Fluent::Clock.freeze(c1) do
128
+ sleep 0.1
129
+ assert_equal c1, Fluent::Clock.now
130
+ Fluent::Clock.freeze(c2) do
131
+ sleep 0.1
132
+ assert_equal c2, Fluent::Clock.now
133
+ end
134
+ assert_equal c1, Fluent::Clock.now
135
+ end
136
+ assert_equal c0, Fluent::Clock.now
137
+ end
138
+ assert{ Fluent::Clock.now > c0 }
139
+ end
140
+ end
141
+
142
+ sub_test_case 'using #freeze with Time argument' do
143
+ test 'Clock.freeze returns the clock value which should be produced when the time is at the specified time' do
144
+ c0 = Fluent::Clock.now
145
+ t0 = Time.now
146
+ t1 = t0 - 30
147
+ assert_kind_of Time, t1
148
+ t2 = t0 + 30
149
+ assert_kind_of Time, t2
150
+
151
+ # 31 is for error of floating point value
152
+ Fluent::Clock.freeze(t1) do
153
+ c1 = Fluent::Clock.now
154
+ assert{ c1 >= c0 - 31 && c1 <= c0 - 31 + 10 } # +10 is for threading schedule error
155
+ end
156
+
157
+ # 29 is for error of floating point value
158
+ Fluent::Clock.freeze(t2) do
159
+ c2 = Fluent::Clock.now
160
+ assert{ c2 >= c0 + 29 && c2 <= c0 + 29 + 10 } # +10 is for threading schedule error
161
+ end
162
+ end
163
+ end
164
+ end
@@ -1,4 +1,5 @@
1
1
  require_relative 'helper'
2
+ require 'fluent/test/driver/input'
2
3
  require 'fluent/engine'
3
4
  require 'fluent/log'
4
5
  require 'timecop'
@@ -374,12 +375,8 @@ class LogTest < Test::Unit::TestCase
374
375
  log1 = Fluent::Log.new(logger)
375
376
  log2 = log1.dup
376
377
  log1.level = Fluent::Log::LEVEL_DEBUG
377
- original_tag = log1.tag
378
- log1.tag = "changed"
379
378
  assert_equal(Fluent::Log::LEVEL_DEBUG, log1.level)
380
379
  assert_equal(Fluent::Log::LEVEL_TRACE, log2.level)
381
- assert_equal("changed", log1.tag)
382
- assert_equal(original_tag, log2.tag)
383
380
  end
384
381
 
385
382
  def test_disable_events
@@ -388,6 +385,7 @@ class LogTest < Test::Unit::TestCase
388
385
  logdev = @log_device
389
386
  logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
390
387
  log = Fluent::Log.new(logger)
388
+ log.enable_event(true)
391
389
  engine = log.instance_variable_get("@engine")
392
390
  mock(engine).push_log_event(anything, anything, anything).once
393
391
  log.trace "trace log"
@@ -535,6 +533,146 @@ class PluginLoggerTest < Test::Unit::TestCase
535
533
  assert_equal(true, @logger.enable_color?)
536
534
  end
537
535
 
536
+ def test_log_type_in_default
537
+ mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_TRACE).once
538
+ mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_DEBUG).once
539
+ mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_INFO).once
540
+ mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_WARN).once
541
+ mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_ERROR).once
542
+ mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_FATAL).once
543
+
544
+ @logger.trace "trace log 1"
545
+ @logger.debug "debug log 2"
546
+ @logger.info "info log 3"
547
+ @logger.warn "warn log 4"
548
+ @logger.error "error log 5"
549
+ @logger.fatal "fatal log 6"
550
+ end
551
+
552
+ def test_log_types
553
+ mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_TRACE).once
554
+ mock(@logger).caller_line(:supervisor, Time.now, 1, Fluent::Log::LEVEL_DEBUG).once
555
+ mock(@logger).caller_line(:worker0, Time.now, 1, Fluent::Log::LEVEL_INFO).once
556
+ mock(@logger).caller_line(:default, Time.now, 1, Fluent::Log::LEVEL_WARN).once
557
+ mock(@logger).caller_line(:supervisor, Time.now, 1, Fluent::Log::LEVEL_ERROR).once
558
+ mock(@logger).caller_line(:worker0, Time.now, 1, Fluent::Log::LEVEL_FATAL).once
559
+
560
+ @logger.trace :default, "trace log 1"
561
+ @logger.debug :supervisor, "debug log 2"
562
+ @logger.info :worker0, "info log 3"
563
+ @logger.warn :default, "warn log 4"
564
+ @logger.error :supervisor, "error log 5"
565
+ @logger.fatal :worker0, "fatal log 6"
566
+ end
567
+
568
+ sub_test_case "supervisor process type" do
569
+ setup do
570
+ dl_opts = {}
571
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
572
+ logdev = @log_device
573
+ logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
574
+ @logger = Fluent::Log.new(logger, process_type: :supervisor)
575
+ end
576
+
577
+ test 'default type logs are shown w/o worker id' do
578
+ @logger.info "yaaay"
579
+ @logger.info :default, "booo"
580
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
581
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: booo\n") }
582
+ end
583
+
584
+ test 'supervisor type logs are shown w/o worker id' do
585
+ @logger.info :supervisor, "yaaay"
586
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
587
+ end
588
+
589
+ test 'worker0 type logs are not shown' do
590
+ @logger.info :worker0, "yaaay"
591
+ assert{ !@log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
592
+ end
593
+ end
594
+
595
+ sub_test_case "worker0 process type" do
596
+ setup do
597
+ dl_opts = {}
598
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
599
+ logdev = @log_device
600
+ logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
601
+ @logger = Fluent::Log.new(logger, process_type: :worker0, worker_id: 10)
602
+ end
603
+
604
+ test 'default type logs are shown w/ worker id' do
605
+ @logger.info "yaaay"
606
+ @logger.info :default, "booo"
607
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: #10 yaaay\n") }
608
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: #10 booo\n") }
609
+ end
610
+
611
+ test 'supervisor type logs are not shown' do
612
+ @logger.info :supervisor, "yaaay"
613
+ assert{ !@log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
614
+ end
615
+
616
+ test 'worker0 type logs are shown w/o worker id' do
617
+ @logger.info :worker0, "yaaay"
618
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
619
+ end
620
+ end
621
+
622
+ sub_test_case "workers process type" do
623
+ setup do
624
+ dl_opts = {}
625
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
626
+ logdev = @log_device
627
+ logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
628
+ @logger = Fluent::Log.new(logger, process_type: :workers, worker_id: 7)
629
+ end
630
+
631
+ test 'default type logs are shown w/ worker id' do
632
+ @logger.info "yaaay"
633
+ @logger.info :default, "booo"
634
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: #7 yaaay\n") }
635
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: #7 booo\n") }
636
+ end
637
+
638
+ test 'supervisor type logs are not shown' do
639
+ @logger.info :supervisor, "yaaay"
640
+ assert{ !@log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
641
+ end
642
+
643
+ test 'worker0 type logs are not shown' do
644
+ @logger.info :worker0, "yaaay"
645
+ assert{ !@log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
646
+ end
647
+ end
648
+
649
+ sub_test_case "standalone process type" do
650
+ setup do
651
+ dl_opts = {}
652
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
653
+ logdev = @log_device
654
+ logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
655
+ @logger = Fluent::Log.new(logger, process_type: :standalone, worker_id: 0)
656
+ end
657
+
658
+ test 'default type logs are shown w/o worker id' do
659
+ @logger.info "yaaay"
660
+ @logger.info :default, "booo"
661
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
662
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: booo\n") }
663
+ end
664
+
665
+ test 'supervisor type logs are shown w/o worker id' do
666
+ @logger.info :supervisor, "yaaay"
667
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
668
+ end
669
+
670
+ test 'worker0 type logs are shown w/o worker id' do
671
+ @logger.info :worker0, "yaaay"
672
+ assert{ @log_device.logs.include?("#{@timestamp_str} [info]: yaaay\n") }
673
+ end
674
+ end
675
+
538
676
  sub_test_case "delegators" do
539
677
  def setup
540
678
  super
@@ -556,12 +694,6 @@ class PluginLoggerTest < Test::Unit::TestCase
556
694
  @log.disable_events(Thread.current)
557
695
  end
558
696
 
559
- def test_tag
560
- assert_equal(@log.tag, @logger.tag)
561
- @log.tag = "dummy"
562
- assert_equal(@log.tag, @logger.tag)
563
- end
564
-
565
697
  def test_time_format
566
698
  assert_equal(@log.time_format, @logger.time_format)
567
699
  @log.time_format = "time_format"
@@ -609,12 +741,11 @@ class PluginLoggerTest < Test::Unit::TestCase
609
741
  end
610
742
 
611
743
  class PluginLoggerMixinTest < Test::Unit::TestCase
612
- class DummyPlugin < Fluent::Plugin::TestBase
613
- include Fluent::PluginHelper::EventEmitter
744
+ class DummyPlugin < Fluent::Plugin::Input
614
745
  end
615
746
 
616
747
  def create_driver(conf)
617
- Fluent::Test::TestDriver.new(DummyPlugin).configure(conf)
748
+ Fluent::Test::Driver::Input.new(DummyPlugin).configure(conf)
618
749
  end
619
750
 
620
751
  def setup
@@ -635,9 +766,9 @@ class PluginLoggerMixinTest < Test::Unit::TestCase
635
766
  end
636
767
 
637
768
  def test_optional_header
638
- d = create_driver(%[log_level fatal])
769
+ d = create_driver(%[@id myplugin])
639
770
  log = d.instance.log
640
- assert_equal("[PluginLoggerMixinTest::DummyPlugin] ", log.optional_header)
771
+ assert_equal("[myplugin] ", log.optional_header)
641
772
  assert_equal({}, log.optional_attrs)
642
773
  end
643
774
 
@@ -0,0 +1,251 @@
1
+ require_relative 'helper'
2
+
3
+ require 'fluent/plugin'
4
+ require 'fluent/plugin/input'
5
+ require 'fluent/plugin/filter'
6
+ require 'fluent/plugin/output'
7
+ require 'fluent/plugin/buffer'
8
+ require 'fluent/plugin/parser'
9
+ require 'fluent/plugin/formatter'
10
+ require 'fluent/plugin/storage'
11
+
12
+ class PluginTest < Test::Unit::TestCase
13
+ class Dummy1Input < Fluent::Plugin::Input
14
+ Fluent::Plugin.register_input('plugin_test_dummy1', self)
15
+ end
16
+ class Dummy2Input < Fluent::Plugin::Input
17
+ Fluent::Plugin.register_input('plugin_test_dummy2', self)
18
+ helpers :storage
19
+ config_section :storage do
20
+ config_set_default :@type, 'plugin_test_dummy1'
21
+ end
22
+ def multi_workers_ready?
23
+ true
24
+ end
25
+ end
26
+ class DummyFilter < Fluent::Plugin::Filter
27
+ Fluent::Plugin.register_filter('plugin_test_dummy', self)
28
+ helpers :parser, :formatter
29
+ config_section :parse do
30
+ config_set_default :@type, 'plugin_test_dummy'
31
+ end
32
+ config_section :format do
33
+ config_set_default :@type, 'plugin_test_dummy'
34
+ end
35
+ def filter(tag, time, record)
36
+ record
37
+ end
38
+ end
39
+ class Dummy1Output < Fluent::Plugin::Output
40
+ Fluent::Plugin.register_output('plugin_test_dummy1', self)
41
+ def write(chunk)
42
+ # drop
43
+ end
44
+ end
45
+ class Dummy2Output < Fluent::Plugin::Output
46
+ Fluent::Plugin.register_output('plugin_test_dummy2', self)
47
+ config_section :buffer do
48
+ config_set_default :@type, 'plugin_test_dummy1'
49
+ end
50
+ def multi_workers_ready?
51
+ true
52
+ end
53
+ def write(chunk)
54
+ # drop
55
+ end
56
+ end
57
+ class Dummy1Buffer < Fluent::Plugin::Buffer
58
+ Fluent::Plugin.register_buffer('plugin_test_dummy1', self)
59
+ end
60
+ class Dummy2Buffer < Fluent::Plugin::Buffer
61
+ Fluent::Plugin.register_buffer('plugin_test_dummy2', self)
62
+ def multi_workers_ready?
63
+ false
64
+ end
65
+ end
66
+ class DummyParser < Fluent::Plugin::Parser
67
+ Fluent::Plugin.register_parser('plugin_test_dummy', self)
68
+ end
69
+ class DummyFormatter < Fluent::Plugin::Formatter
70
+ Fluent::Plugin.register_formatter('plugin_test_dummy', self)
71
+ end
72
+ class Dummy1Storage < Fluent::Plugin::Storage
73
+ Fluent::Plugin.register_storage('plugin_test_dummy1', self)
74
+ end
75
+ class Dummy2Storage < Fluent::Plugin::Storage
76
+ Fluent::Plugin.register_storage('plugin_test_dummy2', self)
77
+ def multi_workers_ready?
78
+ false
79
+ end
80
+ end
81
+ class DummyOwner < Fluent::Plugin::Base
82
+ include Fluent::PluginId
83
+ include Fluent::PluginLoggerMixin
84
+ end
85
+ class DummyEventRouter
86
+ def emit(tag, time, record); end
87
+ def emit_array(tag, array); end
88
+ def emit_stream(tag, es); end
89
+ def emit_error_event(tag, time, record, error); end
90
+ end
91
+
92
+ sub_test_case '#new_* methods' do
93
+ data(
94
+ input1: ['plugin_test_dummy1', Dummy1Input, :new_input],
95
+ input2: ['plugin_test_dummy2', Dummy2Input, :new_input],
96
+ filter: ['plugin_test_dummy', DummyFilter, :new_filter],
97
+ output1: ['plugin_test_dummy1', Dummy1Output, :new_output],
98
+ output2: ['plugin_test_dummy2', Dummy2Output, :new_output],
99
+ )
100
+ test 'retruns plugin instances of registered plugin classes' do |(type, klass, m)|
101
+ instance = Fluent::Plugin.__send__(m, type)
102
+ assert_kind_of klass, instance
103
+ end
104
+
105
+ data(
106
+ buffer1: ['plugin_test_dummy1', Dummy1Buffer, :new_buffer],
107
+ buffer2: ['plugin_test_dummy2', Dummy2Buffer, :new_buffer],
108
+ parser: ['plugin_test_dummy', DummyParser, :new_parser],
109
+ formatter: ['plugin_test_dummy', DummyFormatter, :new_formatter],
110
+ storage1: ['plugin_test_dummy1', Dummy1Storage, :new_storage],
111
+ storage2: ['plugin_test_dummy2', Dummy2Storage, :new_storage],
112
+ )
113
+ test 'returns plugin instances of registered owned plugin classes' do |(type, klass, m)|
114
+ owner = DummyOwner.new
115
+ instance = Fluent::Plugin.__send__(m, type, parent: owner)
116
+ assert_kind_of klass, instance
117
+ end
118
+
119
+ data(
120
+ input1: ['plugin_test_dummy1', Dummy1Input, :new_input, nil],
121
+ input2: ['plugin_test_dummy2', Dummy2Input, :new_input, nil],
122
+ filter: ['plugin_test_dummy', DummyFilter, :new_filter, nil],
123
+ output1: ['plugin_test_dummy1', Dummy1Output, :new_output, nil],
124
+ output2: ['plugin_test_dummy2', Dummy2Output, :new_output, nil],
125
+ buffer1: ['plugin_test_dummy1', Dummy1Buffer, :new_buffer, {parent: DummyOwner.new}],
126
+ buffer2: ['plugin_test_dummy2', Dummy2Buffer, :new_buffer, {parent: DummyOwner.new}],
127
+ parser: ['plugin_test_dummy', DummyParser, :new_parser, {parent: DummyOwner.new}],
128
+ formatter: ['plugin_test_dummy', DummyFormatter, :new_formatter, {parent: DummyOwner.new}],
129
+ storage1: ['plugin_test_dummy1', Dummy1Storage, :new_storage, {parent: DummyOwner.new}],
130
+ storage2: ['plugin_test_dummy2', Dummy2Storage, :new_storage, {parent: DummyOwner.new}],
131
+ )
132
+ test 'returns plugin instances which are extended by FeatureAvailabilityChecker module' do |(type, _, m, kwargs)|
133
+ instance = if kwargs
134
+ Fluent::Plugin.__send__(m, type, **kwargs)
135
+ else
136
+ Fluent::Plugin.__send__(m, type)
137
+ end
138
+ assert_kind_of Fluent::Plugin::FeatureAvailabilityChecker, instance
139
+ end
140
+ end
141
+
142
+ sub_test_case 'with default system configuration' do
143
+ data(
144
+ input1: ['plugin_test_dummy1', Dummy1Input, :new_input, nil],
145
+ input2: ['plugin_test_dummy2', Dummy2Input, :new_input, nil],
146
+ filter: ['plugin_test_dummy', DummyFilter, :new_filter, nil],
147
+ output1: ['plugin_test_dummy1', Dummy1Output, :new_output, nil],
148
+ output2: ['plugin_test_dummy2', Dummy2Output, :new_output, nil],
149
+ buffer1: ['plugin_test_dummy1', Dummy1Buffer, :new_buffer, {parent: DummyOwner.new}],
150
+ buffer2: ['plugin_test_dummy2', Dummy2Buffer, :new_buffer, {parent: DummyOwner.new}],
151
+ parser: ['plugin_test_dummy', DummyParser, :new_parser, {parent: DummyOwner.new}],
152
+ formatter: ['plugin_test_dummy', DummyFormatter, :new_formatter, {parent: DummyOwner.new}],
153
+ storage1: ['plugin_test_dummy1', Dummy1Storage, :new_storage, {parent: DummyOwner.new}],
154
+ storage2: ['plugin_test_dummy2', Dummy2Storage, :new_storage, {parent: DummyOwner.new}],
155
+ )
156
+ test '#configure does not raise anything' do |(type, _, m, kwargs)|
157
+ instance = if kwargs
158
+ Fluent::Plugin.__send__(m, type, **kwargs)
159
+ else
160
+ Fluent::Plugin.__send__(m, type)
161
+ end
162
+ if instance.respond_to?(:context_router=)
163
+ instance.context_router = DummyEventRouter.new
164
+ end
165
+ assert_nothing_raised do
166
+ instance.configure(config_element())
167
+ end
168
+ end
169
+ end
170
+
171
+ sub_test_case 'with single worker configuration' do
172
+ data(
173
+ input1: ['plugin_test_dummy1', Dummy1Input, :new_input, nil],
174
+ input2: ['plugin_test_dummy2', Dummy2Input, :new_input, nil],
175
+ filter: ['plugin_test_dummy', DummyFilter, :new_filter, nil],
176
+ output1: ['plugin_test_dummy1', Dummy1Output, :new_output, nil],
177
+ output2: ['plugin_test_dummy2', Dummy2Output, :new_output, nil],
178
+ buffer1: ['plugin_test_dummy1', Dummy1Buffer, :new_buffer, {parent: DummyOwner.new}],
179
+ buffer2: ['plugin_test_dummy2', Dummy2Buffer, :new_buffer, {parent: DummyOwner.new}],
180
+ parser: ['plugin_test_dummy', DummyParser, :new_parser, {parent: DummyOwner.new}],
181
+ formatter: ['plugin_test_dummy', DummyFormatter, :new_formatter, {parent: DummyOwner.new}],
182
+ storage1: ['plugin_test_dummy1', Dummy1Storage, :new_storage, {parent: DummyOwner.new}],
183
+ storage2: ['plugin_test_dummy2', Dummy2Storage, :new_storage, {parent: DummyOwner.new}],
184
+ )
185
+ test '#configure does not raise anything' do |(type, _, m, kwargs)|
186
+ instance = if kwargs
187
+ Fluent::Plugin.__send__(m, type, **kwargs)
188
+ else
189
+ Fluent::Plugin.__send__(m, type)
190
+ end
191
+ if instance.respond_to?(:context_router=)
192
+ instance.context_router = DummyEventRouter.new
193
+ end
194
+ assert_nothing_raised do
195
+ instance.system_config_override('workers' => 1)
196
+ instance.configure(config_element())
197
+ end
198
+ end
199
+ end
200
+
201
+ sub_test_case 'with multi workers configuration' do
202
+ data(
203
+ input1: ['plugin_test_dummy1', Dummy1Input, :new_input],
204
+ output1: ['plugin_test_dummy1', Dummy1Output, :new_output],
205
+ )
206
+ test '#configure raise configuration error if plugins are not ready for multi workers' do |(type, klass, new_method)|
207
+ conf = config_element()
208
+ instance = Fluent::Plugin.__send__(new_method, type)
209
+ if instance.respond_to?(:context_router=)
210
+ instance.context_router = DummyEventRouter.new
211
+ end
212
+ assert_raise Fluent::ConfigError.new("Plugin '#{type}' does not support multi workers configuration (#{klass})") do
213
+ instance.system_config_override('workers' => 3)
214
+ instance.configure(conf)
215
+ end
216
+ end
217
+
218
+ data(
219
+ input2: ['plugin_test_dummy2', Dummy2Input, :new_input], # with Dummy1Storage
220
+ filter: ['plugin_test_dummy', DummyFilter, :new_filter], # with DummyParser and DummyFormatter
221
+ output2: ['plugin_test_dummy2', Dummy2Output, :new_output], # with Dummy1Buffer
222
+ )
223
+ test '#configure does not raise any errors if plugins and its owned plugins are ready for multi workers' do |(type, _klass, new_method)|
224
+ conf = config_element()
225
+ instance = Fluent::Plugin.__send__(new_method, type)
226
+ if instance.respond_to?(:context_router=)
227
+ instance.context_router = DummyEventRouter.new
228
+ end
229
+ assert_nothing_raised do
230
+ instance.system_config_override('workers' => 3)
231
+ instance.configure(conf)
232
+ end
233
+ end
234
+
235
+ data(
236
+ input2: ['plugin_test_dummy2', Dummy2Input, :new_input, 'storage', 'plugin_test_dummy2', Dummy2Storage],
237
+ output2: ['plugin_test_dummy2', Dummy2Output, :new_output, 'buffer', 'plugin_test_dummy2', Dummy2Buffer],
238
+ )
239
+ test '#configure raise configuration error if configured owned plugins are not ready for multi workers' do |(type, _klass, new_method, subsection, subsection_type, problematic)|
240
+ conf = config_element('root', '', {}, [config_element(subsection, '', {'@type' => subsection_type})])
241
+ instance = Fluent::Plugin.__send__(new_method, type)
242
+ if instance.respond_to?(:context_router=)
243
+ instance.context_router = DummyEventRouter.new
244
+ end
245
+ assert_raise Fluent::ConfigError.new("Plugin '#{subsection_type}' does not support multi workers configuration (#{problematic})") do
246
+ instance.system_config_override('workers' => 3)
247
+ instance.configure(conf)
248
+ end
249
+ end
250
+ end
251
+ end