fluentd 1.7.4-x64-mingw32 → 1.8.0-x64-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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -1
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +70 -0
  5. data/MAINTAINERS.md +1 -0
  6. data/example/out_forward_sd.conf +17 -0
  7. data/example/sd.yaml +8 -0
  8. data/fluentd.gemspec +1 -1
  9. data/lib/fluent/agent.rb +3 -1
  10. data/lib/fluent/command/cat.rb +1 -2
  11. data/lib/fluent/command/fluentd.rb +16 -8
  12. data/lib/fluent/compat/call_super_mixin.rb +9 -0
  13. data/lib/fluent/compat/exec_util.rb +1 -1
  14. data/lib/fluent/config/configure_proxy.rb +4 -4
  15. data/lib/fluent/config/element.rb +28 -15
  16. data/lib/fluent/config/error.rb +6 -0
  17. data/lib/fluent/config/literal_parser.rb +24 -2
  18. data/lib/fluent/config/section.rb +43 -6
  19. data/lib/fluent/config/types.rb +98 -26
  20. data/lib/fluent/configurable.rb +2 -2
  21. data/lib/fluent/counter/base_socket.rb +2 -4
  22. data/lib/fluent/engine.rb +41 -122
  23. data/lib/fluent/event.rb +5 -7
  24. data/lib/fluent/fluent_log_event_router.rb +141 -0
  25. data/lib/fluent/msgpack_factory.rb +19 -2
  26. data/lib/fluent/plugin.rb +10 -1
  27. data/lib/fluent/plugin/base.rb +2 -2
  28. data/lib/fluent/plugin/buf_file.rb +11 -7
  29. data/lib/fluent/plugin/buf_file_single.rb +8 -5
  30. data/lib/fluent/plugin/buffer/chunk.rb +1 -1
  31. data/lib/fluent/plugin/buffer/file_chunk.rb +4 -6
  32. data/lib/fluent/plugin/buffer/file_single_chunk.rb +3 -5
  33. data/lib/fluent/plugin/formatter_csv.rb +23 -1
  34. data/lib/fluent/plugin/formatter_stdout.rb +1 -1
  35. data/lib/fluent/plugin/in_forward.rb +1 -1
  36. data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
  37. data/lib/fluent/plugin/in_tail.rb +6 -0
  38. data/lib/fluent/plugin/in_unix.rb +1 -1
  39. data/lib/fluent/plugin/out_forward.rb +77 -28
  40. data/lib/fluent/plugin/out_forward/ack_handler.rb +1 -1
  41. data/lib/fluent/plugin/out_forward/load_balancer.rb +5 -2
  42. data/lib/fluent/plugin/out_stream.rb +1 -1
  43. data/lib/fluent/plugin/output.rb +11 -3
  44. data/lib/fluent/plugin/parser.rb +1 -0
  45. data/lib/fluent/plugin/sd_file.rb +155 -0
  46. data/lib/fluent/plugin/sd_static.rb +58 -0
  47. data/lib/fluent/plugin/service_discovery.rb +80 -0
  48. data/lib/fluent/plugin_helper.rb +1 -0
  49. data/lib/fluent/plugin_helper/child_process.rb +3 -3
  50. data/lib/fluent/plugin_helper/compat_parameters.rb +11 -1
  51. data/lib/fluent/plugin_helper/extract.rb +1 -1
  52. data/lib/fluent/plugin_helper/inject.rb +1 -1
  53. data/lib/fluent/plugin_helper/record_accessor.rb +10 -19
  54. data/lib/fluent/plugin_helper/server.rb +8 -4
  55. data/lib/fluent/plugin_helper/service_discovery.rb +80 -0
  56. data/lib/fluent/plugin_helper/service_discovery/manager.rb +132 -0
  57. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  58. data/lib/fluent/plugin_id.rb +7 -0
  59. data/lib/fluent/root_agent.rb +7 -9
  60. data/lib/fluent/supervisor.rb +192 -211
  61. data/lib/fluent/system_config.rb +26 -52
  62. data/lib/fluent/test/driver/base_owned.rb +15 -2
  63. data/lib/fluent/time.rb +8 -6
  64. data/lib/fluent/version.rb +1 -1
  65. data/test/command/test_fluentd.rb +12 -7
  66. data/test/config/test_configurable.rb +154 -0
  67. data/test/config/test_element.rb +18 -0
  68. data/test/config/test_literal_parser.rb +4 -0
  69. data/test/config/test_system_config.rb +48 -91
  70. data/test/config/test_types.rb +293 -120
  71. data/test/counter/test_client.rb +8 -4
  72. data/test/plugin/data/sd_file/config +11 -0
  73. data/test/plugin/data/sd_file/config.json +17 -0
  74. data/test/plugin/data/sd_file/config.yaml +11 -0
  75. data/test/plugin/data/sd_file/config.yml +11 -0
  76. data/test/plugin/data/sd_file/invalid_config.yml +7 -0
  77. data/test/plugin/out_forward/test_handshake_protocol.rb +2 -2
  78. data/test/plugin/out_forward/test_load_balancer.rb +1 -1
  79. data/test/plugin/out_forward/test_socket_cache.rb +2 -2
  80. data/test/plugin/test_buf_file.rb +40 -0
  81. data/test/plugin/test_buf_file_single.rb +32 -0
  82. data/test/plugin/test_buffer_file_chunk.rb +0 -11
  83. data/test/plugin/test_buffer_file_single_chunk.rb +0 -10
  84. data/test/plugin/test_formatter_csv.rb +9 -0
  85. data/test/plugin/test_in_forward.rb +9 -9
  86. data/test/plugin/test_in_monitor_agent.rb +37 -10
  87. data/test/plugin/test_in_unix.rb +5 -5
  88. data/test/plugin/test_out_forward.rb +45 -1
  89. data/test/plugin/test_out_stdout.rb +36 -1
  90. data/test/plugin/test_out_stream.rb +3 -3
  91. data/test/plugin/test_output.rb +25 -1
  92. data/test/plugin/test_sd_file.rb +211 -0
  93. data/test/plugin_helper/service_discovery/test_manager.rb +93 -0
  94. data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +21 -0
  95. data/test/plugin_helper/test_server.rb +13 -0
  96. data/test/plugin_helper/test_service_discovery.rb +72 -0
  97. data/test/test_event.rb +15 -15
  98. data/test/test_fluent_log_event_router.rb +99 -0
  99. data/test/test_logger_initializer.rb +26 -0
  100. data/test/test_supervisor.rb +30 -59
  101. metadata +43 -6
@@ -27,11 +27,12 @@ module Fluent
27
27
  :log_event_verbose,
28
28
  :without_source, :rpc_endpoint, :enable_get_dump, :process_name,
29
29
  :file_permission, :dir_permission, :counter_server, :counter_client,
30
+ :strict_config_value
30
31
  ]
31
32
 
32
33
  config_param :workers, :integer, default: 1
33
34
  config_param :root_dir, :string, default: nil
34
- config_param :log_level, :enum, list: [:trace, :debug, :info, :warn, :error, :fatal], default: nil
35
+ config_param :log_level, :enum, list: [:trace, :debug, :info, :warn, :error, :fatal], default: 'info'
35
36
  config_param :suppress_repeated_stacktrace, :bool, default: nil
36
37
  config_param :emit_error_log_interval, :time, default: nil
37
38
  config_param :suppress_config_dump, :bool, default: nil
@@ -40,6 +41,7 @@ module Fluent
40
41
  config_param :rpc_endpoint, :string, default: nil
41
42
  config_param :enable_get_dump, :bool, default: nil
42
43
  config_param :process_name, :string, default: nil
44
+ config_param :strict_config_value, :bool, default: nil
43
45
  config_param :file_permission, default: nil do |v|
44
46
  v.to_i(8)
45
47
  end
@@ -73,12 +75,12 @@ module Fluent
73
75
  config_param :timeout, :time, default: nil
74
76
  end
75
77
 
76
- def self.create(conf)
78
+ def self.create(conf, strict_config_value=false)
77
79
  systems = conf.elements(name: 'system')
78
80
  return SystemConfig.new if systems.empty?
79
81
  raise Fluent::ConfigError, "<system> is duplicated. <system> should be only one" if systems.size > 1
80
82
 
81
- SystemConfig.new(systems.first)
83
+ SystemConfig.new(systems.first, strict_config_value)
82
84
  end
83
85
 
84
86
  def self.blank_system_config
@@ -95,14 +97,26 @@ module Fluent
95
97
  end
96
98
  end
97
99
 
98
- def initialize(conf=nil)
100
+ def initialize(conf=nil, strict_config_value=false)
99
101
  super()
100
102
  conf ||= SystemConfig.blank_system_config
101
- configure(conf)
103
+ configure(conf, strict_config_value)
102
104
  end
103
105
 
104
- def configure(conf)
105
- super
106
+ def configure(conf, strict_config_value=false)
107
+ strict = strict_config_value
108
+ if !strict && conf && conf.has_key?("strict_config_value")
109
+ strict = Fluent::Config.bool_value(conf["strict_config_value"])
110
+ end
111
+
112
+ begin
113
+ super(conf, strict)
114
+ rescue ConfigError => e
115
+ $log.error "config error in:\n#{conf}"
116
+ $log.error 'config error', error: e
117
+ $log.debug_backtrace
118
+ exit!(1)
119
+ end
106
120
 
107
121
  @log_level = Log.str_to_level(@log_level.to_s) if @log_level
108
122
  end
@@ -115,52 +129,12 @@ module Fluent
115
129
  s
116
130
  end
117
131
 
118
- def attach(supervisor)
119
- system = self
120
- supervisor.instance_eval {
121
- SYSTEM_CONFIG_PARAMETERS.each do |param|
122
- case param
123
- when :rpc_endpoint, :enable_get_dump, :process_name, :file_permission, :dir_permission, :counter_server, :counter_client
124
- next # doesn't exist in command line options
125
- when :emit_error_log_interval
126
- system.emit_error_log_interval = @suppress_interval if @suppress_interval
127
- when :log_level
128
- ll_value = instance_variable_get("@log_level")
129
- # info level can't be specified via command line option.
130
- # log_level is info here, it is default value and <system>'s log_level should be applied if exists.
131
- if ll_value != Fluent::Log::LEVEL_INFO
132
- system.log_level = ll_value
133
- end
134
- else
135
- next unless instance_variable_defined?("@#{param}")
136
- supervisor_value = instance_variable_get("@#{param}")
137
- next if supervisor_value.nil? # it's not configured by command line options
138
-
139
- system.__send__("#{param}=", supervisor_value)
140
- end
141
- end
142
- }
143
- end
144
-
145
- def apply(supervisor)
146
- system = self
147
- supervisor.instance_eval {
148
- SYSTEM_CONFIG_PARAMETERS.each do |param|
149
- param_value = system.__send__(param)
150
- next if param_value.nil?
151
-
152
- case param
153
- when :log_level
154
- @log.level = @log_level = param_value
155
- when :emit_error_log_interval
156
- @suppress_interval = param_value
157
- else
158
- instance_variable_set("@#{param}", param_value)
159
- end
132
+ def overwrite_variables(**opt)
133
+ SYSTEM_CONFIG_PARAMETERS.each do |param|
134
+ if opt.key?(param) && !opt[param].nil? && instance_variable_defined?("@#{param}")
135
+ instance_variable_set("@#{param}", opt[param])
160
136
  end
161
- #@counter_server = system.counter_server unless system.counter_server.nil?
162
- #@counter_client = system.counter_client unless system.counter_client.nil?
163
- }
137
+ end
164
138
  end
165
139
 
166
140
  module Mixin
@@ -53,13 +53,26 @@ module Fluent
53
53
  @section_name = ''
54
54
  end
55
55
 
56
- def configure(conf, syntax: :v1)
56
+ def configure(conf)
57
57
  if conf.is_a?(Fluent::Config::Element)
58
58
  @config = conf
59
59
  elsif conf.is_a?(Hash)
60
60
  @config = Fluent::Config::Element.new(@section_name, "", Hash[conf.map{|k,v| [k.to_s, v]}], [])
61
61
  else
62
- @config = Fluent::Config.parse(conf, @section_name, "", syntax: syntax)
62
+ @config = Fluent::Config.parse(conf, @section_name, "", syntax: :v1)
63
+ end
64
+ @instance.configure(@config)
65
+ self
66
+ end
67
+
68
+ # this is special method for v0 and should be deleted
69
+ def configure_v0(conf)
70
+ if conf.is_a?(Fluent::Config::Element)
71
+ @config = conf
72
+ elsif conf.is_a?(Hash)
73
+ @config = Fluent::Config::Element.new(@section_name, "", Hash[conf.map{|k,v| [k.to_s, v]}], [])
74
+ else
75
+ @config = Fluent::Config.parse(conf, @section_name, "", syntax: :v0)
63
76
  end
64
77
  @instance.configure(@config)
65
78
  self
@@ -147,14 +147,12 @@ module Fluent
147
147
  module TimeParameters
148
148
  include Fluent::Configurable
149
149
  TIME_FULL_PARAMETERS.each do |name, type, opts|
150
- config_param name, type, opts
150
+ config_param(name, type, **opts)
151
151
  end
152
152
 
153
153
  def configure(conf)
154
154
  if conf.has_key?('localtime') || conf.has_key?('utc')
155
- if conf.has_key?('localtime') && conf.has_key?('utc')
156
- raise Fluent::ConfigError, "both of utc and localtime are specified, use only one of them"
157
- elsif conf.has_key?('localtime')
155
+ if conf.has_key?('localtime')
158
156
  conf['localtime'] = Fluent::Config.bool_value(conf['localtime'])
159
157
  elsif conf.has_key?('utc')
160
158
  conf['localtime'] = !(Fluent::Config.bool_value(conf['utc']))
@@ -167,6 +165,10 @@ module Fluent
167
165
 
168
166
  super
169
167
 
168
+ if conf.has_key?('localtime') && conf.has_key?('utc') && !(@localtime ^ @utc)
169
+ raise Fluent::ConfigError, "both of utc and localtime are specified, use only one of them"
170
+ end
171
+
170
172
  Fluent::Timezone.validate!(@timezone) if @timezone
171
173
  end
172
174
  end
@@ -292,7 +294,7 @@ module Fluent
292
294
 
293
295
  def parse_unixtime(value)
294
296
  unless value.is_a?(String) || value.is_a?(Numeric)
295
- raise TimeParseError, "value must be a string or a number: #{value}(value.class)"
297
+ raise TimeParseError, "value must be a string or a number: #{value}(#{value.class})"
296
298
  end
297
299
 
298
300
  if @cache1_key == value
@@ -323,7 +325,7 @@ module Fluent
323
325
  ## parse_by_to_r (msec): 28.232856 sec
324
326
  def parse_float(value)
325
327
  unless value.is_a?(String) || value.is_a?(Numeric)
326
- raise TimeParseError, "value must be a string or a number: #{value}(value.class)"
328
+ raise TimeParseError, "value must be a string or a number: #{value}(#{value.class})"
327
329
  end
328
330
 
329
331
  if @cache1_key == value
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.7.4'
19
+ VERSION = '1.8.0'
20
20
 
21
21
  end
@@ -317,7 +317,8 @@ CONF
317
317
  create_cmdline(conf_path),
318
318
  "fluentd worker is now running",
319
319
  'fluent.info: {"worker":0,"message":"fluentd worker is now running worker=0"}',
320
- patterns_not_match: ['[warn]: some tags for log events are not defined (to be ignored) tags=["fluent.trace", "fluent.debug"]'],
320
+ "define <match fluent.**> to capture fluentd logs in top level is deprecated. Use <label @FLUENT_LOG> instead",
321
+ patterns_not_match: ['[warn]: some tags for log events are not defined in top level (to be ignored) tags=["fluent.trace", "fluent.debug"]'],
321
322
  )
322
323
  end
323
324
 
@@ -331,7 +332,8 @@ CONF
331
332
  assert_log_matches(
332
333
  create_cmdline(conf_path),
333
334
  "fluentd worker is now running",
334
- '[warn]: #0 match for some tags of log events are not defined (to be ignored) tags=["fluent.trace", "fluent.debug", "fluent.info"]',
335
+ '[warn]: #0 match for some tags of log events are not defined in top level (to be ignored) tags=["fluent.trace", "fluent.debug", "fluent.info"]',
336
+ "define <match fluent.warn>, <match fluent.error>, <match fluent.fatal> to capture fluentd logs in top level is deprecated. Use <label @FLUENT_LOG> instead",
335
337
  '[warn]: #0 no patterns matched tag="fluent.info"',
336
338
  )
337
339
  end
@@ -349,7 +351,7 @@ CONF
349
351
  create_cmdline(conf_path),
350
352
  "fluentd worker is now running",
351
353
  'fluent.info: {"worker":0,"message":"fluentd worker is now running worker=0"}',
352
- patterns_not_match: ['[warn]: some tags for log events are not defined (to be ignored)'],
354
+ patterns_not_match: ['[warn]: some tags for log events are not defined in @FLUENT_LOG label (to be ignored)'],
353
355
  )
354
356
  end
355
357
 
@@ -368,7 +370,7 @@ CONF
368
370
  assert_log_matches(
369
371
  create_cmdline(conf_path),
370
372
  "fluentd worker is now running",
371
- '[warn]: #0 match for some tags of log events are not defined (to be ignored) tags=["fluent.info", "fluent.fatal"]',
373
+ '[warn]: #0 match for some tags of log events are not defined in @FLUENT_LOG label (to be ignored) tags=["fluent.info", "fluent.fatal"]',
372
374
  patterns_not_match: ['[warn]: no patterns matched tag="fluent.info"'],
373
375
  )
374
376
  end
@@ -625,7 +627,8 @@ CONF
625
627
  workers 2
626
628
  </system>
627
629
  <source>
628
- @type single
630
+ @type dummy
631
+ tag dummy
629
632
  @id single
630
633
  @label @dummydata
631
634
  </source>
@@ -669,7 +672,8 @@ EOC
669
672
  workers 2
670
673
  </system>
671
674
  <source>
672
- @type single
675
+ @type dummy
676
+ tag dummy
673
677
  @id single
674
678
  @label @dummydata
675
679
  </source>
@@ -793,7 +797,7 @@ CONF
793
797
  @id blackhole
794
798
  <buffer>
795
799
  @type file
796
- path #{File.join(@root_path, "buf", "file.*.log")}
800
+ path #{File.join(@root_path, "buf")}
797
801
  </buffer>
798
802
  </match>
799
803
  </worker>
@@ -863,6 +867,7 @@ module Fluent::Plugin
863
867
  class FakeInput < Input
864
868
  Fluent::Plugin.register_input('fake', self)
865
869
  config_param :secret, :string, secret: true
870
+ def multi_workers_ready?; true; end
866
871
  end
867
872
  end
868
873
  EOC
@@ -30,6 +30,13 @@ module ConfigurableSpec
30
30
  config_set_default :opt1, :baz
31
31
  end
32
32
 
33
+ class Base1Nil < Base1
34
+ config_set_default :name1, nil
35
+ config_set_default :name2, nil
36
+ config_set_default :opt1, nil
37
+ config_param :name5, :string, default: nil
38
+ end
39
+
33
40
  class Base2 < Base1
34
41
  config_set_default :name2, "base2"
35
42
  config_set_default :name4, "base2"
@@ -214,6 +221,12 @@ module ConfigurableSpec
214
221
  end
215
222
  end
216
223
 
224
+ class ExampleWithIntFloat
225
+ include Fluent::Configurable
226
+ config_param :int1, :integer
227
+ config_param :float1, :float
228
+ end
229
+
217
230
  module Overwrite
218
231
  class Base
219
232
  include Fluent::Configurable
@@ -602,7 +615,69 @@ module Fluent::Config
602
615
  assert_equal([], x6a.obj2)
603
616
  end
604
617
  end
618
+
619
+ test 'strict value type' do
620
+ default = config_element("", "", {"int1" => "1", "float1" => ""})
621
+
622
+ c = ConfigurableSpec::ExampleWithIntFloat.new
623
+ assert_nothing_raised { c.configure(default) }
624
+ assert_raise(Fluent::ConfigError) { c.configure(default, true) }
625
+ end
605
626
  end
627
+
628
+ test 'set nil for a parameter which has no default value' do
629
+ obj = ConfigurableSpec::Base2.new
630
+ conf = config_element("", "", {"name1" => nil, "name5" => "t5", "opt3" => "a"})
631
+ assert_raise(Fluent::ConfigError.new("'name1' parameter is required but nil is specified")) do
632
+ obj.configure(conf)
633
+ end
634
+ end
635
+
636
+ test 'set nil for a parameter which has non-nil default value' do
637
+ obj = ConfigurableSpec::Base2.new
638
+ conf = config_element("", "", {"name1" => "t1", "name3" => nil, "name5" => "t5", "opt3" => "a"})
639
+ assert_raise(Fluent::ConfigError.new("'name3' parameter is required but nil is specified")) do
640
+ obj.configure(conf)
641
+ end
642
+ end
643
+
644
+ test 'set nil for a parameter whose default value is nil' do
645
+ obj = ConfigurableSpec::Base1Nil.new
646
+ conf = config_element("", "", {"name5" => nil})
647
+ obj.configure(conf)
648
+ assert_nil obj.name5
649
+ end
650
+
651
+ test 'set nil for parameters whose default values are overwritten by nil' do
652
+ obj = ConfigurableSpec::Base1Nil.new
653
+ conf = config_element("", "", {"name1" => nil, "name2" => nil, "opt1" => nil})
654
+ obj.configure(conf)
655
+ assert_nil obj.name1
656
+ assert_nil obj.name2
657
+ assert_nil obj.opt1
658
+ end
659
+
660
+ test 'set :default' do
661
+ obj = ConfigurableSpec::Base2.new
662
+ conf = config_element("", "", {"name1" => "t1", "name3" => :default, "name5" => "t5", "opt3" => "a"})
663
+ obj.configure(conf)
664
+ assert_equal "base1", obj.name3
665
+ end
666
+
667
+ test 'set :default for a parameter which has no default value' do
668
+ obj = ConfigurableSpec::Base2.new
669
+ conf = config_element("", "", {"name1" => :default, "name5" => "t5", "opt3" => "a"})
670
+ assert_raise(Fluent::ConfigError.new("'name1' doesn't have default value")) do
671
+ obj.configure(conf)
672
+ end
673
+ end
674
+
675
+ test 'set :default for a parameter which has an overwritten default value' do
676
+ obj = ConfigurableSpec::Base2.new
677
+ conf = config_element("", "", {"name1" => "t1", "name3" => "t3", "name4" => :default, "name5" => "t5", "opt3" => "a"})
678
+ obj.configure(conf)
679
+ assert_equal "base2", obj.name4
680
+ end
606
681
  end
607
682
 
608
683
  sub_test_case 'class defined with config_section' do
@@ -1626,5 +1701,84 @@ module Fluent::Config
1626
1701
  assert_equal 'foo', c.subsection.first.param0
1627
1702
  end
1628
1703
  end
1704
+
1705
+ sub_test_case '#config_argument' do
1706
+ test 'with strict_config_value' do
1707
+ class TestClass01
1708
+ include Fluent::Configurable
1709
+ config_section :subsection do
1710
+ config_argument :param1, :integer
1711
+ end
1712
+ end
1713
+
1714
+ c = TestClass01.new
1715
+ subsection = config_element('subsection', "hoge", { })
1716
+ assert_raise(Fluent::ConfigError.new('param1: invalid value for Integer(): "hoge"')) do
1717
+ c.configure(config_element('root', '', {}, [subsection]), true)
1718
+ end
1719
+ end
1720
+
1721
+ test 'with nil' do
1722
+ class TestClass02
1723
+ include Fluent::Configurable
1724
+ config_section :subsection do
1725
+ config_argument :param1, :integer
1726
+ end
1727
+ end
1728
+
1729
+ c = TestClass02.new
1730
+ subsection = config_element('subsection', nil, { })
1731
+ assert_raise(Fluent::ConfigError.new("'<subsection ARG>' section requires argument, in section subsection")) do
1732
+ c.configure(config_element('root', '', {}, [subsection]))
1733
+ end
1734
+ end
1735
+
1736
+ test 'with nil for an argument whose default value is nil' do
1737
+ class TestClass03
1738
+ include Fluent::Configurable
1739
+ config_section :subsection do
1740
+ config_argument :param1, :integer, default: nil
1741
+ end
1742
+ end
1743
+
1744
+ c = TestClass03.new
1745
+ subsection = config_element('subsection', nil, { })
1746
+ c.configure(config_element('root', '', {}, [subsection]))
1747
+
1748
+ assert_equal 1, c.subsection.size
1749
+ assert_equal nil, c.subsection.first.param1
1750
+ end
1751
+
1752
+ test 'with :default' do
1753
+ class TestClass04
1754
+ include Fluent::Configurable
1755
+ config_section :subsection do
1756
+ config_argument :param1, :integer, default: 3
1757
+ end
1758
+ end
1759
+
1760
+ c = TestClass04.new
1761
+ subsection = config_element('subsection', :default, { })
1762
+ c.configure(config_element('root', '', {}, [subsection]))
1763
+
1764
+ assert_equal 1, c.subsection.size
1765
+ assert_equal 3, c.subsection.first.param1
1766
+ end
1767
+
1768
+ test 'with :default for an argument which does not have default value' do
1769
+ class TestClass05
1770
+ include Fluent::Configurable
1771
+ config_section :subsection do
1772
+ config_argument :param1, :integer
1773
+ end
1774
+ end
1775
+
1776
+ c = TestClass05.new
1777
+ subsection = config_element('subsection', :default, { })
1778
+ assert_raise(Fluent::ConfigError.new("'param1' doesn\'t have default value")) do
1779
+ c.configure(config_element('root', '', {}, [subsection]))
1780
+ end
1781
+ end
1782
+ end
1629
1783
  end
1630
1784
  end