fluentd 1.8.0.rc3 → 1.8.0

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.

@@ -152,9 +152,7 @@ module Fluent
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
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.8.0.rc3'
19
+ VERSION = '1.8.0'
20
20
 
21
21
  end
@@ -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
@@ -254,6 +254,24 @@ CONF
254
254
  assert_not_equal(e.inspect, e.to_s)
255
255
  assert_equal(dump, e.to_s)
256
256
  end
257
+
258
+ test 'dump nil and default for v1' do
259
+ expected = <<-CONF
260
+ <ROOT>
261
+ str1
262
+ str2 defstring
263
+ </ROOT>
264
+ CONF
265
+ e = element('ROOT', '', {'str1' => nil, "str2" => :default}, [])
266
+ type_lookup = ->(type){ Fluent::Configurable.lookup_type(type) }
267
+ p = Fluent::Config::ConfigureProxy.new("test", type_lookup: type_lookup)
268
+ p.config_param :str1, :string
269
+ p.config_param :str2, :string, default: "defstring"
270
+ e.corresponding_proxies << p
271
+ e.v1_config = true
272
+ assert_not_equal(e.inspect, e.to_s)
273
+ assert_equal(expected, e.to_s)
274
+ end
257
275
  end
258
276
 
259
277
  sub_test_case '#inspect' do
@@ -240,6 +240,10 @@ module Fluent::Config
240
240
  assert_text_parsed_as("foo1", '"foo#{worker_id}"')
241
241
  ENV.delete('SERVERENGINE_WORKER_ID')
242
242
  }
243
+ test('nil') { assert_text_parsed_as(nil, '"#{raise SetNil}"') }
244
+ test('default') { assert_text_parsed_as(:default, '"#{raise SetDefault}"') }
245
+ test('nil helper') { assert_text_parsed_as(nil, '"#{use_nil}"') }
246
+ test('default helper') { assert_text_parsed_as(:default, '"#{use_default}"') }
243
247
  end
244
248
 
245
249
  sub_test_case 'array parsing' do
@@ -71,7 +71,7 @@ module Fluent::Config
71
71
  sc.overwrite_variables(s.for_system_config)
72
72
  assert_equal(1, sc.workers)
73
73
  assert_nil(sc.root_dir)
74
- assert_nil(sc.log_level)
74
+ assert_equal(Fluent::Log::LEVEL_INFO, sc.log_level)
75
75
  assert_nil(sc.suppress_repeated_stacktrace)
76
76
  assert_nil(sc.emit_error_log_interval)
77
77
  assert_nil(sc.suppress_config_dump)
@@ -88,6 +88,7 @@ module Fluent::Config
88
88
  'log_event_verbose' => ['log_event_verbose', true],
89
89
  'suppress_config_dump' => ['suppress_config_dump', true],
90
90
  'without_source' => ['without_source', true],
91
+ 'strict_config_value' => ['strict_config_value', true],
91
92
  )
92
93
  test "accepts parameters" do |(k, v)|
93
94
  conf = parse_text(<<-EOS)
@@ -5,59 +5,122 @@ class TestConfigTypes < ::Test::Unit::TestCase
5
5
  include Fluent
6
6
 
7
7
  sub_test_case 'Config.size_value' do
8
- test 'normal case' do
9
- assert_equal(2048, Config.size_value("2k"))
10
- assert_equal(2048, Config.size_value("2K"))
11
- assert_equal(3145728, Config.size_value("3m"))
12
- assert_equal(3145728, Config.size_value("3M"))
13
- assert_equal(4294967296, Config.size_value("4g"))
14
- assert_equal(4294967296, Config.size_value("4G"))
15
- assert_equal(5497558138880, Config.size_value("5t"))
16
- assert_equal(5497558138880, Config.size_value("5T"))
17
- assert_equal(6, Config.size_value("6"))
18
- end
19
-
20
- test 'not assumed case' do
21
- assert_equal(6, Config.size_value(6))
22
- assert_equal(0, Config.size_value("hoge"))
23
- assert_equal(0, Config.size_value(""))
24
- assert_equal(0, Config.size_value(nil))
8
+ data("2k" => [2048, "2k"],
9
+ "2K" => [2048, "2K"],
10
+ "3m" => [3145728, "3m"],
11
+ "3M" => [3145728, "3M"],
12
+ "4g" => [4294967296, "4g"],
13
+ "4G" => [4294967296, "4G"],
14
+ "5t" => [5497558138880, "5t"],
15
+ "5T" => [5497558138880, "5T"],
16
+ "6" => [6, "6"])
17
+ test 'normal case' do |(expected, val)|
18
+ assert_equal(expected, Config.size_value(val))
19
+ assert_equal(expected, Config.size_value(val, { strict: true }))
20
+ end
21
+
22
+ data("integer" => [6, 6],
23
+ "hoge" => [0, "hoge"],
24
+ "empty" => [0, ""])
25
+ test 'not assumed case' do |(expected, val)|
26
+ assert_equal(expected, Config.size_value(val))
27
+ end
28
+
29
+ test 'nil' do
30
+ assert_equal(nil, Config.size_value(nil))
31
+ end
32
+
33
+ data("integer" => [6, 6],
34
+ "hoge" => [Fluent::ConfigError.new('name1: invalid value for Integer(): "hoge"'), "hoge"],
35
+ "empty" => [Fluent::ConfigError.new('name1: invalid value for Integer(): ""'), ""])
36
+ test 'not assumed case with strict' do |(expected, val)|
37
+ if expected.kind_of? Exception
38
+ assert_raise(expected) do
39
+ Config.size_value(val, { strict: true }, "name1")
40
+ end
41
+ else
42
+ assert_equal(expected, Config.size_value(val, { strict: true }, "name1"))
43
+ end
44
+ end
45
+
46
+ test 'nil with strict' do
47
+ assert_equal(nil, Config.size_value(nil, { strict: true }))
25
48
  end
26
49
  end
27
50
 
28
51
  sub_test_case 'Config.time_value' do
29
- test 'normal case' do
30
- assert_equal(10, Config.time_value("10s"))
31
- assert_equal(10, Config.time_value("10sec"))
32
- assert_equal(120, Config.time_value("2m"))
33
- assert_equal(10800, Config.time_value("3h"))
34
- assert_equal(345600, Config.time_value("4d"))
52
+ data("10s" => [10, "10s"],
53
+ "10sec" => [10, "10sec"],
54
+ "2m" => [120, "2m"],
55
+ "3h" => [10800, "3h"],
56
+ "4d" => [345600, "4d"])
57
+ test 'normal case' do |(expected, val)|
58
+ assert_equal(expected, Config.time_value(val))
59
+ assert_equal(expected, Config.time_value(val, { strict: true }))
35
60
  end
36
61
 
37
- test 'not assumed case' do
38
- assert_equal(4.0, Config.time_value(4))
39
- assert_equal(0.4, Config.time_value(0.4))
40
- assert_equal(0.0, Config.time_value("hoge"))
41
- assert_equal(0.0, Config.time_value(""))
42
- assert_equal(0.0, Config.time_value(nil))
62
+ data("integer" => [4.0, 4],
63
+ "float" => [0.4, 0.4],
64
+ "hoge" => [0.0, "hoge"],
65
+ "empty" => [0.0, ""])
66
+ test 'not assumed case' do |(expected, val)|
67
+ assert_equal(expected, Config.time_value(val))
68
+ end
69
+
70
+ test 'nil' do
71
+ assert_equal(nil, Config.time_value(nil))
72
+ end
73
+
74
+ data("integer" => [6, 6],
75
+ "hoge" => [Fluent::ConfigError.new('name1: invalid value for Float(): "hoge"'), "hoge"],
76
+ "empty" => [Fluent::ConfigError.new('name1: invalid value for Float(): ""'), ""])
77
+ test 'not assumed case with strict' do |(expected, val)|
78
+ if expected.kind_of? Exception
79
+ assert_raise(expected) do
80
+ Config.time_value(val, { strict: true }, "name1")
81
+ end
82
+ else
83
+ assert_equal(expected, Config.time_value(val, { strict: true }, "name1"))
84
+ end
85
+ end
86
+
87
+ test 'nil with strict' do
88
+ assert_equal(nil, Config.time_value(nil, { strict: true }))
43
89
  end
44
90
  end
45
91
 
46
92
  sub_test_case 'Config.bool_value' do
47
- test 'normal case' do
48
- assert_true Config.bool_value("true")
49
- assert_true Config.bool_value("yes")
50
- assert_true Config.bool_value("")
51
- assert_false Config.bool_value("false")
52
- assert_false Config.bool_value("no")
93
+ data("true" => [true, "true"],
94
+ "yes" => [true, "yes"],
95
+ "empty" => [true, ""],
96
+ "false" => [false, "false"],
97
+ "no" => [false, "no"])
98
+ test 'normal case' do |(expected, val)|
99
+ assert_equal(expected, Config.bool_value(val))
53
100
  end
54
101
 
55
- test 'not assumed case' do
56
- assert_true Config.bool_value(true)
57
- assert_false Config.bool_value(false)
58
- assert_nil Config.bool_value("hoge")
59
- assert_nil Config.bool_value(nil)
60
- assert_nil Config.bool_value(10)
102
+ data("true" => [true, true],
103
+ "false" => [false, false],
104
+ "hoge" => [nil, "hoge"],
105
+ "nil" => [nil, nil],
106
+ "integer" => [nil, 10])
107
+ test 'not assumed case' do |(expected, val)|
108
+ assert_equal(expected, Config.bool_value(val))
109
+ end
110
+
111
+ data("true" => [true, true],
112
+ "false" => [false, false],
113
+ "hoge" => [Fluent::ConfigError.new("name1: invalid bool value: hoge"), "hoge"],
114
+ "nil" => [nil, nil],
115
+ "integer" => [Fluent::ConfigError.new("name1: invalid bool value: 10"), 10])
116
+ test 'not assumed case with strict' do |(expected, val)|
117
+ if expected.kind_of? Exception
118
+ assert_raise(expected) do
119
+ Config.bool_value(val, { strict: true }, "name1")
120
+ end
121
+ else
122
+ assert_equal(expected, Config.bool_value(val, { strict: true }, "name1"))
123
+ end
61
124
  end
62
125
  end
63
126
 
@@ -87,14 +150,23 @@ class TestConfigTypes < ::Test::Unit::TestCase
87
150
  Config.regexp_value(str)
88
151
  end
89
152
  end
153
+
154
+ test 'nil' do
155
+ assert_equal nil, Config.regexp_value(nil)
156
+ end
90
157
  end
91
158
 
92
159
  sub_test_case 'type converters for config_param definitions' do
93
- test 'string' do
94
- assert_equal 'test', Config::STRING_TYPE.call('test', {})
95
- assert_equal '1', Config::STRING_TYPE.call('1', {})
96
- assert_equal ' ', Config::STRING_TYPE.call(' ', {})
97
- assert_equal Encoding::UTF_8, Config::STRING_TYPE.call('test', {}).encoding
160
+ data("test" => ['test', 'test'],
161
+ "1" => ['1', '1'],
162
+ "spaces" => [' ', ' '])
163
+ test 'string' do |(expected, val)|
164
+ assert_equal expected, Config::STRING_TYPE.call(val, {})
165
+ assert_equal Encoding::UTF_8, Config::STRING_TYPE.call(val, {}).encoding
166
+ end
167
+
168
+ test 'string nil' do
169
+ assert_equal nil, Config::STRING_TYPE.call(nil, {})
98
170
  end
99
171
 
100
172
  data('latin' => 'Märch',
@@ -108,58 +180,133 @@ class TestConfigTypes < ::Test::Unit::TestCase
108
180
  assert_equal Encoding::UTF_8, actual.encoding
109
181
  end
110
182
 
111
- test 'enum' do
112
- assert_equal :val, Config::ENUM_TYPE.call('val', {list: [:val, :value, :v]})
113
- assert_equal :v, Config::ENUM_TYPE.call('v', {list: [:val, :value, :v]})
114
- assert_equal :value, Config::ENUM_TYPE.call('value', {list: [:val, :value, :v]})
115
- assert_raises(Fluent::ConfigError.new("valid options are val,value,v but got x")){ Config::ENUM_TYPE.call('x', {list: [:val, :value, :v]}) }
116
- assert_raises(RuntimeError.new("Plugin BUG: config type 'enum' requires :list of symbols")){ Config::ENUM_TYPE.call('val', {}) }
117
- assert_raises(RuntimeError.new("Plugin BUG: config type 'enum' requires :list of symbols")){ Config::ENUM_TYPE.call('val', {list: ["val", "value", "v"]}) }
183
+ data("val" => [:val, 'val'],
184
+ "v" => [:v, 'v'],
185
+ "value" => [:value, 'value'])
186
+ test 'enum' do |(expected, val, list)|
187
+ assert_equal expected, Config::ENUM_TYPE.call(val, {list: [:val, :value, :v]})
188
+ end
189
+
190
+ test 'enum: pick unknown choice' do
191
+ assert_raises(Fluent::ConfigError.new("valid options are val,value,v but got x")) do
192
+ Config::ENUM_TYPE.call('x', {list: [:val, :value, :v]})
193
+ end
194
+ end
195
+
196
+ data("empty list" => {},
197
+ "string list" => {list: ["val", "value", "v"]})
198
+ test 'enum: invalid choices' do | list |
199
+ assert_raises(RuntimeError.new("Plugin BUG: config type 'enum' requires :list of symbols")) do
200
+ Config::ENUM_TYPE.call('val', list)
201
+ end
118
202
  end
119
203
 
120
- test 'integer' do
121
- assert_equal 1, Config::INTEGER_TYPE.call('1', {})
122
- assert_equal 1, Config::INTEGER_TYPE.call('1.0', {})
123
- assert_equal 1000, Config::INTEGER_TYPE.call('1_000', {})
124
- assert_equal 1, Config::INTEGER_TYPE.call('1x', {})
204
+ test 'enum: nil' do
205
+ assert_equal nil, Config::ENUM_TYPE.call(nil)
125
206
  end
126
207
 
127
- test 'float' do
128
- assert_equal 1.0, Config::FLOAT_TYPE.call('1', {})
129
- assert_equal 1.0, Config::FLOAT_TYPE.call('1.0', {})
130
- assert_equal 1.0, Config::FLOAT_TYPE.call('1.00', {})
131
- assert_equal 1.0, Config::FLOAT_TYPE.call('1e0', {})
208
+ data("1" => [1, '1'],
209
+ "1.0" => [1, '1.0'],
210
+ "1_000" => [1000, '1_000'],
211
+ "1x" => [1, '1x'])
212
+ test 'integer' do |(expected, val)|
213
+ assert_equal expected, Config::INTEGER_TYPE.call(val, {})
132
214
  end
133
215
 
134
- test 'size' do
135
- assert_equal 1000, Config::SIZE_TYPE.call('1000', {})
136
- assert_equal 1024, Config::SIZE_TYPE.call('1k', {})
137
- assert_equal 1024*1024, Config::SIZE_TYPE.call('1m', {})
216
+ data("integer" => [6, 6],
217
+ "hoge" => [0, "hoge"],
218
+ "empty" => [0, ""])
219
+ test 'integer: not assumed case' do |(expected, val)|
220
+ assert_equal expected, Config::INTEGER_TYPE.call(val, {})
138
221
  end
139
222
 
140
- test 'bool' do
141
- assert_equal true, Config::BOOL_TYPE.call('true', {})
142
- assert_equal true, Config::BOOL_TYPE.call('yes', {})
143
- assert_equal false, Config::BOOL_TYPE.call('no', {})
144
- assert_equal false, Config::BOOL_TYPE.call('false', {})
223
+ test 'integer: nil' do
224
+ assert_equal nil, Config::INTEGER_TYPE.call(nil, {})
225
+ end
145
226
 
146
- assert_equal nil, Config::BOOL_TYPE.call('TRUE', {})
147
- assert_equal nil, Config::BOOL_TYPE.call('True', {})
148
- assert_equal nil, Config::BOOL_TYPE.call('Yes', {})
149
- assert_equal nil, Config::BOOL_TYPE.call('No', {})
227
+ data("integer" => [6, 6],
228
+ "hoge" => [Fluent::ConfigError.new('name1: invalid value for Integer(): "hoge"'), "hoge"],
229
+ "empty" => [Fluent::ConfigError.new('name1: invalid value for Integer(): ""'), ""])
230
+ test 'integer: not assumed case with strict' do |(expected, val)|
231
+ if expected.kind_of? Exception
232
+ assert_raise(expected) do
233
+ Config::INTEGER_TYPE.call(val, { strict: true }, "name1")
234
+ end
235
+ else
236
+ assert_equal expected, Config::INTEGER_TYPE.call(val, { strict: true }, "name1")
237
+ end
238
+ end
150
239
 
151
- assert_equal true, Config::BOOL_TYPE.call('', {})
152
- assert_equal nil, Config::BOOL_TYPE.call('unexpected_string', {})
240
+ test 'integer: nil with strict' do
241
+ assert_equal nil, Config::INTEGER_TYPE.call(nil, { strict: true })
153
242
  end
154
243
 
155
- test 'time' do
156
- assert_equal 0, Config::TIME_TYPE.call('0', {})
157
- assert_equal 1.0, Config::TIME_TYPE.call('1', {})
158
- assert_equal 1.01, Config::TIME_TYPE.call('1.01', {})
159
- assert_equal 1, Config::TIME_TYPE.call('1s', {})
160
- assert_equal 60, Config::TIME_TYPE.call('1m', {})
161
- assert_equal 3600, Config::TIME_TYPE.call('1h', {})
162
- assert_equal 86400, Config::TIME_TYPE.call('1d', {})
244
+ data("1" => [1.0, '1'],
245
+ "1.0" => [1.0, '1.0'],
246
+ "1.00" => [1.0, '1.00'],
247
+ "1e0" => [1.0, '1e0'])
248
+ test 'float' do |(expected, val)|
249
+ assert_equal expected, Config::FLOAT_TYPE.call(val, {})
250
+ end
251
+
252
+ data("integer" => [6, 6],
253
+ "hoge" => [0, "hoge"],
254
+ "empty" => [0, ""])
255
+ test 'float: not assumed case' do |(expected, val)|
256
+ assert_equal expected, Config::FLOAT_TYPE.call(val, {})
257
+ end
258
+
259
+ test 'float: nil' do
260
+ assert_equal nil, Config::FLOAT_TYPE.call(nil, {})
261
+ end
262
+
263
+ data("integer" => [6, 6],
264
+ "hoge" => [Fluent::ConfigError.new('name1: invalid value for Float(): "hoge"'), "hoge"],
265
+ "empty" => [Fluent::ConfigError.new('name1: invalid value for Float(): ""'), ""])
266
+ test 'float: not assumed case with strict' do |(expected, val)|
267
+ if expected.kind_of? Exception
268
+ assert_raise(expected) do
269
+ Config::FLOAT_TYPE.call(val, { strict: true }, "name1")
270
+ end
271
+ else
272
+ assert_equal expected, Config::FLOAT_TYPE.call(val, { strict: true }, "name1")
273
+ end
274
+ end
275
+
276
+ test 'float: nil with strict' do
277
+ assert_equal nil, Config::FLOAT_TYPE.call(nil, { strict: true })
278
+ end
279
+
280
+ data("1000" => [1000, '1000'],
281
+ "1k" => [1024, '1k'],
282
+ "1m" => [1024*1024, '1m'])
283
+ test 'size' do |(expected, val)|
284
+ assert_equal expected, Config::SIZE_TYPE.call(val, {})
285
+ end
286
+
287
+ data("true" => [true, 'true'],
288
+ "yes" => [true, 'yes'],
289
+ "no" => [false, 'no'],
290
+ "false" => [false, 'false'],
291
+ "TRUE" => [nil, 'TRUE'],
292
+ "True" => [nil, 'True'],
293
+ "Yes" => [nil, 'Yes'],
294
+ "No" => [nil, 'No'],
295
+ "empty" => [true, ''],
296
+ "unexpected_string" => [nil, 'unexpected_string'])
297
+ test 'bool' do |(expected, val)|
298
+ assert_equal expected, Config::BOOL_TYPE.call(val, {})
299
+ end
300
+
301
+ data("0" => [0, '0'],
302
+ "1" => [1.0, '1'],
303
+ "1.01" => [1.01, '1.01'],
304
+ "1s" => [1, '1s'],
305
+ "1," => [60, '1m'],
306
+ "1h" => [3600, '1h'],
307
+ "1d" => [86400, '1d'])
308
+ test 'time' do |(expected, val)|
309
+ assert_equal expected, Config::TIME_TYPE.call(val, {})
163
310
  end
164
311
 
165
312
  data("empty" => [//, "//"],
@@ -171,24 +318,32 @@ class TestConfigTypes < ::Test::Unit::TestCase
171
318
  assert_equal(expected, Config::REGEXP_TYPE.call(str, {}))
172
319
  end
173
320
 
174
- test 'hash' do
175
- assert_equal({"x"=>"v","k"=>1}, Config::HASH_TYPE.call('{"x":"v","k":1}', {}))
176
- assert_equal({"x"=>"v","k"=>"1"}, Config::HASH_TYPE.call('x:v,k:1', {}))
177
- assert_equal({"x"=>"v","k"=>"1"}, Config::HASH_TYPE.call('x:v, k:1', {}))
178
- assert_equal({"x"=>"v","k"=>"1"}, Config::HASH_TYPE.call(' x:v, k:1 ', {}))
179
- assert_equal({"x"=>"v","k"=>"1"}, Config::HASH_TYPE.call('x:v , k:1 ', {}))
180
-
181
- assert_equal({"x"=>"v:v","k"=>"1"}, Config::HASH_TYPE.call('x:v:v, k:1', {}))
182
-
183
- assert_equal({x: "v", k: 1}, Config::HASH_TYPE.call('{"x":"v","k":1}', {symbolize_keys: true}))
184
- assert_equal({x: "v", k: "1"}, Config::HASH_TYPE.call('x:v,k:1', {symbolize_keys: true, value_type: :string}))
185
- assert_equal({x: "v", k: "1"}, Config::HASH_TYPE.call('{"x":"v","k":1}', {symbolize_keys: true, value_type: :string}))
186
- assert_equal({x: 0, k: 1}, Config::HASH_TYPE.call('x:0,k:1', {symbolize_keys: true, value_type: :integer}))
321
+ data("string and integer" => [{"x"=>"v","k"=>1}, '{"x":"v","k":1}', {}],
322
+ "strings" => [{"x"=>"v","k"=>"1"}, 'x:v,k:1', {}],
323
+ "w/ space" => [{"x"=>"v","k"=>"1"}, 'x:v, k:1', {}],
324
+ "heading space" => [{"x"=>"v","k"=>"1"}, ' x:v, k:1 ', {}],
325
+ "trailing space" => [{"x"=>"v","k"=>"1"}, 'x:v , k:1 ', {}],
326
+ "multiple colons" => [{"x"=>"v:v","k"=>"1"}, 'x:v:v, k:1', {}],
327
+ "symbolize keys" => [{x: "v", k: 1}, '{"x":"v","k":1}', {symbolize_keys: true}],
328
+ "value_type: :string" => [{x: "v", k: "1"}, 'x:v,k:1', {symbolize_keys: true, value_type: :string}],
329
+ "value_type: :string 2" => [{x: "v", k: "1"}, '{"x":"v","k":1}', {symbolize_keys: true, value_type: :string}],
330
+ "value_type: :integer" => [{x: 0, k: 1}, 'x:0,k:1', {symbolize_keys: true, value_type: :integer}],
331
+ "time 1" => [{"x"=>1,"y"=>60,"z"=>3600}, '{"x":"1s","y":"1m","z":"1h"}', {value_type: :time}],
332
+ "time 2" => [{"x"=>1,"y"=>60,"z"=>3600}, 'x:1s,y:1m,z:1h', {value_type: :time}])
333
+ test 'hash' do |(expected, val, opts)|
334
+ assert_equal(expected, Config::HASH_TYPE.call(val, opts))
335
+ end
187
336
 
188
- assert_equal({"x"=>1,"y"=>60,"z"=>3600}, Config::HASH_TYPE.call('{"x":"1s","y":"1m","z":"1h"}', {value_type: :time}))
189
- assert_equal({"x"=>1,"y"=>60,"z"=>3600}, Config::HASH_TYPE.call('x:1s,y:1m,z:1h', {value_type: :time}))
337
+ test 'hash w/ unknown type' do
338
+ assert_raise(RuntimeError.new("unknown type in REFORMAT: foo")) do
339
+ Config::HASH_TYPE.call("x:1,y:2", {value_type: :foo})
340
+ end
341
+ end
190
342
 
191
- assert_raise(RuntimeError.new("unknown type in REFORMAT: foo")){ Config::HASH_TYPE.call("x:1,y:2", {value_type: :foo}) }
343
+ test 'hash w/ strict option' do
344
+ assert_raise(Fluent::ConfigError.new('y: invalid value for Integer(): "hoge"')) do
345
+ Config::HASH_TYPE.call("x:1,y:hoge", {value_type: :integer, strict: true})
346
+ end
192
347
  end
193
348
 
194
349
  data('latin' => ['3:Märch', {"3"=>"Märch"}],
@@ -199,30 +354,48 @@ class TestConfigTypes < ::Test::Unit::TestCase
199
354
  assert_equal(expected, Config::HASH_TYPE.call(target.b, { value_type: :string }))
200
355
  end
201
356
 
202
- test 'array' do
203
- assert_equal(["1","2",1], Config::ARRAY_TYPE.call('["1","2",1]', {}))
204
- assert_equal(["1","2","1"], Config::ARRAY_TYPE.call('1,2,1', {}))
205
-
206
- assert_equal(["a","b","c"], Config::ARRAY_TYPE.call('["a","b","c"]', {}))
207
- assert_equal(["a","b","c"], Config::ARRAY_TYPE.call('a,b,c', {}))
208
- assert_equal(["a","b","c"], Config::ARRAY_TYPE.call('a, b, c', {}))
209
- assert_equal(["a","b","c"], Config::ARRAY_TYPE.call('a , b , c', {}))
210
-
211
- assert_equal(["a a","b,b"," c "], Config::ARRAY_TYPE.call('["a a","b,b"," c "]', {}))
212
-
213
- assert_equal(["a a","b","c"], Config::ARRAY_TYPE.call('a a,b,c', {}))
357
+ test 'hash w/ nil' do
358
+ assert_equal(nil, Config::HASH_TYPE.call(nil))
359
+ end
214
360
 
215
- assert_equal([1,2,1], Config::ARRAY_TYPE.call('[1,2,1]', {}))
216
- assert_equal([1,2,1], Config::ARRAY_TYPE.call('["1","2","1"]', {value_type: :integer}))
217
- assert_equal([1,2,1], Config::ARRAY_TYPE.call('1,2,1', {value_type: :integer}))
361
+ data("strings and integer" => [["1","2",1], '["1","2",1]', {}],
362
+ "number strings" => [["1","2","1"], '1,2,1', {}],
363
+ "alphabets" => [["a","b","c"], '["a","b","c"]', {}],
364
+ "alphabets w/o quote" => [["a","b","c"], 'a,b,c', {}],
365
+ "w/ spaces" => [["a","b","c"], 'a, b, c', {}],
366
+ "w/ space before comma" => [["a","b","c"], 'a , b , c', {}],
367
+ "comma or space w/ qupte" => [["a a","b,b"," c "], '["a a","b,b"," c "]', {}],
368
+ "space in a value w/o qupte" => [["a a","b","c"], 'a a,b,c', {}],
369
+ "integers" => [[1,2,1], '[1,2,1]', {}],
370
+ "value_type: :integer w/ quote" => [[1,2,1], '["1","2","1"]', {value_type: :integer}],
371
+ "value_type: :integer w/o quote" => [[1,2,1], '1,2,1', {value_type: :integer}])
372
+ test 'array' do |(expected, val, opts)|
373
+ assert_equal(expected, Config::ARRAY_TYPE.call(val, opts))
374
+ end
218
375
 
376
+ data('["1","2"]' => [["1","2"], '["1","2"]'],
377
+ '["3"]' => [["3"], '["3"]'])
378
+ test 'array w/ default values' do |(expected, val)|
219
379
  array_options = {
220
380
  default: [],
221
381
  }
222
- assert_equal(["1","2"], Config::ARRAY_TYPE.call('["1","2"]', array_options))
223
- assert_equal(["3"], Config::ARRAY_TYPE.call('["3"]', array_options))
382
+ assert_equal(expected, Config::ARRAY_TYPE.call(val, array_options))
383
+ end
384
+
385
+ test 'array w/ unknown type' do
386
+ assert_raise(RuntimeError.new("unknown type in REFORMAT: foo")) do
387
+ Config::ARRAY_TYPE.call("1,2", {value_type: :foo})
388
+ end
389
+ end
390
+
391
+ test 'array w/ strict option' do
392
+ assert_raise(Fluent::ConfigError.new(': invalid value for Integer(): "hoge"')) do
393
+ Config::ARRAY_TYPE.call("1,hoge", {value_type: :integer, strict: true}, "name1")
394
+ end
395
+ end
224
396
 
225
- assert_raise(RuntimeError.new("unknown type in REFORMAT: foo")){ Config::ARRAY_TYPE.call("1,2", {value_type: :foo}) }
397
+ test 'array w/ nil' do
398
+ assert_equal(nil, Config::ARRAY_TYPE.call(nil))
226
399
  end
227
400
  end
228
401
  end