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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/CHANGELOG.md +24 -2
- data/MAINTAINERS.md +1 -0
- data/lib/fluent/command/fluentd.rb +4 -0
- data/lib/fluent/config/element.rb +28 -15
- data/lib/fluent/config/error.rb +6 -0
- data/lib/fluent/config/literal_parser.rb +24 -2
- data/lib/fluent/config/section.rb +43 -6
- data/lib/fluent/config/types.rb +98 -26
- data/lib/fluent/configurable.rb +2 -2
- data/lib/fluent/engine.rb +6 -6
- data/lib/fluent/plugin/base.rb +1 -1
- data/lib/fluent/plugin/formatter_stdout.rb +1 -1
- data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
- data/lib/fluent/plugin/out_forward.rb +3 -3
- data/lib/fluent/plugin/output.rb +11 -3
- data/lib/fluent/plugin_helper/compat_parameters.rb +11 -1
- data/lib/fluent/supervisor.rb +53 -65
- data/lib/fluent/system_config.rb +21 -7
- data/lib/fluent/time.rb +5 -3
- data/lib/fluent/version.rb +1 -1
- data/test/config/test_configurable.rb +154 -0
- data/test/config/test_element.rb +18 -0
- data/test/config/test_literal_parser.rb +4 -0
- data/test/config/test_system_config.rb +2 -1
- data/test/config/test_types.rb +293 -120
- data/test/plugin/out_forward/test_load_balancer.rb +1 -1
- data/test/plugin/test_in_monitor_agent.rb +2 -1
- data/test/plugin/test_out_stdout.rb +36 -1
- data/test/plugin/test_output.rb +25 -1
- data/test/test_logger_initializer.rb +26 -0
- data/test/test_supervisor.rb +26 -40
- metadata +6 -4
data/lib/fluent/time.rb
CHANGED
@@ -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')
|
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
|
data/lib/fluent/version.rb
CHANGED
@@ -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
|
data/test/config/test_element.rb
CHANGED
@@ -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
|
-
|
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)
|
data/test/config/test_types.rb
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
assert_equal(
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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 '
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
assert_equal
|
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
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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 '
|
121
|
-
assert_equal
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
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 '
|
141
|
-
assert_equal
|
142
|
-
|
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
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
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
|
-
|
152
|
-
assert_equal nil, Config::
|
240
|
+
test 'integer: nil with strict' do
|
241
|
+
assert_equal nil, Config::INTEGER_TYPE.call(nil, { strict: true })
|
153
242
|
end
|
154
243
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
assert_equal
|
161
|
-
|
162
|
-
|
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
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
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
|
-
|
189
|
-
|
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
|
-
|
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 '
|
203
|
-
assert_equal(
|
204
|
-
|
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
|
-
|
216
|
-
|
217
|
-
|
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(
|
223
|
-
|
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
|
-
|
397
|
+
test 'array w/ nil' do
|
398
|
+
assert_equal(nil, Config::ARRAY_TYPE.call(nil))
|
226
399
|
end
|
227
400
|
end
|
228
401
|
end
|