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
@@ -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
@@ -15,20 +15,41 @@ module Fluent::Config
15
15
  class FakeSupervisor
16
16
  attr_writer :log_level
17
17
 
18
- def initialize
19
- @workers = nil
20
- @root_dir = nil
21
- @log = FakeLoggerInitializer.new
22
- @log_level = Fluent::Log::LEVEL_INFO
23
- @suppress_interval = nil
24
- @suppress_config_dump = nil
25
- @suppress_repeated_stacktrace = nil
26
- @log_event_label = nil
27
- @log_event_verbose = nil
28
- @without_source = nil
29
- @emit_error_log_interval = nil
30
- @file_permission = nil
31
- @dir_permission = nil
18
+ def initialize(**opt)
19
+ @system_config = nil
20
+ @cl_opt = {
21
+ wokers: nil,
22
+ root_dir: nil,
23
+ log: FakeLoggerInitializer.new,
24
+ log_level: Fluent::Log::LEVEL_INFO,
25
+ suppress_interval: nil,
26
+ suppress_config_dump: nil,
27
+ suppress_repeated_stacktrace: nil,
28
+ log_event_label: nil,
29
+ log_event_verbose: nil,
30
+ without_source: nil,
31
+ emit_error_log_interval: nil,
32
+ file_permission: nil,
33
+ dir_permission: nil,
34
+ }.merge(opt)
35
+ end
36
+
37
+ def for_system_config
38
+ opt = {}
39
+ # this is copy from Supervisor#build_system_config
40
+ Fluent::SystemConfig::SYSTEM_CONFIG_PARAMETERS.each do |param|
41
+ if @cl_opt.key?(param) && !@cl_opt[param].nil?
42
+ if param == :log_level && @cl_opt[:log_level] == Fluent::Log::LEVEL_INFO
43
+ # info level can't be specified via command line option.
44
+ # log_level is info here, it is default value and <system>'s log_level should be applied if exists.
45
+ next
46
+ end
47
+
48
+ opt[param] = @cl_opt[param]
49
+ end
50
+ end
51
+
52
+ opt
32
53
  end
33
54
  end
34
55
 
@@ -47,26 +68,16 @@ module Fluent::Config
47
68
  EOS
48
69
  s = FakeSupervisor.new
49
70
  sc = Fluent::SystemConfig.new(conf)
50
- sc.apply(s)
71
+ sc.overwrite_variables(s.for_system_config)
51
72
  assert_equal(1, sc.workers)
52
73
  assert_nil(sc.root_dir)
53
- assert_nil(sc.log_level)
74
+ assert_equal(Fluent::Log::LEVEL_INFO, sc.log_level)
54
75
  assert_nil(sc.suppress_repeated_stacktrace)
55
76
  assert_nil(sc.emit_error_log_interval)
56
77
  assert_nil(sc.suppress_config_dump)
57
78
  assert_nil(sc.without_source)
58
79
  assert_equal(:text, sc.log.format)
59
80
  assert_equal('%Y-%m-%d %H:%M:%S %z', sc.log.time_format)
60
- assert_equal(1, s.instance_variable_get(:@workers))
61
- assert_nil(s.instance_variable_get(:@root_dir))
62
- assert_equal(Fluent::Log::LEVEL_INFO, s.instance_variable_get(:@log_level))
63
- assert_nil(s.instance_variable_get(:@suppress_repeated_stacktrace))
64
- assert_nil(s.instance_variable_get(:@emit_error_log_interval))
65
- assert_nil(s.instance_variable_get(:@suppress_config_dump))
66
- assert_nil(s.instance_variable_get(:@log_event_verbose))
67
- assert_nil(s.instance_variable_get(:@without_source))
68
- assert_nil(s.instance_variable_get(:@file_permission))
69
- assert_nil(s.instance_variable_get(:@dir_permission))
70
81
  end
71
82
 
72
83
  data(
@@ -74,10 +85,10 @@ module Fluent::Config
74
85
  'root_dir' => ['root_dir', File.join(TMP_DIR, 'root')],
75
86
  'log_level' => ['log_level', 'error'],
76
87
  'suppress_repeated_stacktrace' => ['suppress_repeated_stacktrace', true],
77
- 'emit_error_log_interval' => ['emit_error_log_interval', 60],
78
88
  'log_event_verbose' => ['log_event_verbose', true],
79
89
  'suppress_config_dump' => ['suppress_config_dump', true],
80
90
  'without_source' => ['without_source', true],
91
+ 'strict_config_value' => ['strict_config_value', true],
81
92
  )
82
93
  test "accepts parameters" do |(k, v)|
83
94
  conf = parse_text(<<-EOS)
@@ -87,10 +98,12 @@ module Fluent::Config
87
98
  EOS
88
99
  s = FakeSupervisor.new
89
100
  sc = Fluent::SystemConfig.new(conf)
90
- sc.apply(s)
91
- assert_not_nil(sc.instance_variable_get("@#{k}"))
92
- key = (k == 'emit_error_log_interval' ? 'suppress_interval' : k)
93
- assert_not_nil(s.instance_variable_get("@#{key}"))
101
+ sc.overwrite_variables(s.for_system_config)
102
+ if k == 'log_level'
103
+ assert_equal(Fluent::Log::LEVEL_ERROR, sc.__send__(k))
104
+ else
105
+ assert_equal(v, sc.__send__(k))
106
+ end
94
107
  end
95
108
 
96
109
  test "log parameters" do
@@ -104,50 +117,11 @@ module Fluent::Config
104
117
  EOS
105
118
  s = FakeSupervisor.new
106
119
  sc = Fluent::SystemConfig.new(conf)
107
- sc.apply(s)
120
+ sc.overwrite_variables(s.for_system_config)
108
121
  assert_equal(:json, sc.log.format)
109
122
  assert_equal('%Y', sc.log.time_format)
110
123
  end
111
124
 
112
- data(
113
- 'foo' => ['foo', 'bar'],
114
- 'hoge' => ['hoge', 'fuga'],
115
- )
116
- test "should not affect settable parameters with unknown parameters" do |(k, v)|
117
- s = FakeSupervisor.new
118
- sc = Fluent::SystemConfig.new({k => v})
119
- sc.apply(s)
120
- assert_equal(1, s.instance_variable_get(:@workers))
121
- assert_nil(s.instance_variable_get(:@root_dir))
122
- assert_equal(Fluent::Log::LEVEL_INFO, s.instance_variable_get(:@log_level))
123
- assert_nil(s.instance_variable_get(:@suppress_repeated_stacktrace))
124
- assert_nil(s.instance_variable_get(:@emit_error_log_interval))
125
- assert_nil(s.instance_variable_get(:@suppress_config_dump))
126
- assert_nil(s.instance_variable_get(:@log_event_verbose))
127
- assert_nil(s.instance_variable_get(:@without_source))
128
- assert_nil(s.instance_variable_get(:@file_permission))
129
- assert_nil(s.instance_variable_get(:@dir_permission))
130
- end
131
-
132
- data('trace' => Fluent::Log::LEVEL_TRACE,
133
- 'debug' => Fluent::Log::LEVEL_DEBUG,
134
- 'info' => Fluent::Log::LEVEL_INFO,
135
- 'warn' => Fluent::Log::LEVEL_WARN,
136
- 'error' => Fluent::Log::LEVEL_ERROR,
137
- 'fatal' => Fluent::Log::LEVEL_FATAL)
138
- test 'log_level is applied when log_level related command line option is not passed' do |level|
139
- conf = parse_text(<<-EOS)
140
- <system>
141
- log_level #{Fluent::Log::LEVEL_TEXT[level]}
142
- </system>
143
- EOS
144
- s = FakeSupervisor.new
145
- sc = Fluent::SystemConfig.new(conf)
146
- sc.attach(s)
147
- sc.apply(s)
148
- assert_equal(level, s.instance_variable_get("@log").level)
149
- end
150
-
151
125
  # info is removed because info level can't be specified via command line
152
126
  data('trace' => Fluent::Log::LEVEL_TRACE,
153
127
  'debug' => Fluent::Log::LEVEL_DEBUG,
@@ -160,27 +134,10 @@ module Fluent::Config
160
134
  log_level info
161
135
  </system>
162
136
  EOS
163
- s = FakeSupervisor.new
164
- s.log_level = level
165
- sc = Fluent::SystemConfig.new(conf)
166
- sc.attach(s)
167
- sc.apply(s)
168
- assert_equal(level, s.instance_variable_get("@log").level)
169
- end
170
-
171
- test 'process global overridable variables' do
172
- conf = parse_text(<<-EOS)
173
- <system>
174
- file_permission 0655
175
- dir_permission 0765
176
- </system>
177
- EOS
178
- s = FakeSupervisor.new
137
+ s = FakeSupervisor.new(log_level: level)
179
138
  sc = Fluent::SystemConfig.new(conf)
180
- sc.attach(s)
181
- sc.apply(s)
182
- assert_equal(0655, s.instance_variable_get(:@file_permission))
183
- assert_equal(0765, s.instance_variable_get(:@dir_permission))
139
+ sc.overwrite_variables(s.for_system_config)
140
+ assert_equal(level, sc.log_level)
184
141
  end
185
142
  end
186
143
  end
@@ -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