fluentd 0.12.0.pre.1 → 0.12.0.pre.2

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +1 -0
  4. data/ChangeLog +21 -0
  5. data/README.md +10 -2
  6. data/Rakefile +4 -13
  7. data/example/v1_literal_example.conf +36 -0
  8. data/fluentd.gemspec +4 -1
  9. data/lib/fluent/buffer.rb +73 -46
  10. data/lib/fluent/command/fluentd.rb +7 -2
  11. data/lib/fluent/config/basic_parser.rb +5 -0
  12. data/lib/fluent/config/element.rb +2 -5
  13. data/lib/fluent/config/literal_parser.rb +26 -7
  14. data/lib/fluent/config/section.rb +2 -0
  15. data/lib/fluent/config/v1_parser.rb +9 -2
  16. data/lib/fluent/formatter.rb +2 -1
  17. data/lib/fluent/mixin.rb +22 -7
  18. data/lib/fluent/output.rb +17 -8
  19. data/lib/fluent/parser.rb +14 -3
  20. data/lib/fluent/plugin/buf_file.rb +30 -15
  21. data/lib/fluent/plugin/filter_grep.rb +69 -0
  22. data/lib/fluent/plugin/filter_record_transformer.rb +183 -0
  23. data/lib/fluent/plugin/in_exec.rb +6 -0
  24. data/lib/fluent/plugin/in_forward.rb +34 -4
  25. data/lib/fluent/plugin/in_http.rb +1 -1
  26. data/lib/fluent/plugin/out_exec.rb +1 -1
  27. data/lib/fluent/plugin/out_exec_filter.rb +8 -1
  28. data/lib/fluent/plugin/out_forward.rb +82 -4
  29. data/lib/fluent/supervisor.rb +1 -1
  30. data/lib/fluent/timezone.rb +131 -0
  31. data/lib/fluent/version.rb +1 -1
  32. data/test/config/assertions.rb +42 -0
  33. data/test/config/test_config_parser.rb +385 -0
  34. data/test/config/test_configurable.rb +530 -0
  35. data/test/config/test_configure_proxy.rb +99 -0
  36. data/test/config/test_dsl.rb +237 -0
  37. data/test/config/test_literal_parser.rb +293 -0
  38. data/test/config/test_section.rb +112 -0
  39. data/test/config/test_system_config.rb +49 -0
  40. data/test/helper.rb +25 -0
  41. data/test/plugin/test_buf_file.rb +604 -0
  42. data/test/plugin/test_buf_memory.rb +204 -0
  43. data/test/plugin/test_filter_grep.rb +124 -0
  44. data/test/plugin/test_filter_record_transformer.rb +251 -0
  45. data/test/plugin/test_in_exec.rb +1 -0
  46. data/test/plugin/test_in_forward.rb +205 -2
  47. data/test/plugin/test_in_gc_stat.rb +1 -0
  48. data/test/plugin/test_in_http.rb +58 -2
  49. data/test/plugin/test_in_object_space.rb +1 -0
  50. data/test/plugin/test_in_status.rb +1 -0
  51. data/test/plugin/test_in_stream.rb +1 -1
  52. data/test/plugin/test_in_syslog.rb +1 -1
  53. data/test/plugin/test_in_tail.rb +1 -0
  54. data/test/plugin/test_in_tcp.rb +1 -1
  55. data/test/plugin/test_in_udp.rb +1 -1
  56. data/test/plugin/test_out_copy.rb +1 -0
  57. data/test/plugin/test_out_exec.rb +1 -0
  58. data/test/plugin/test_out_exec_filter.rb +1 -0
  59. data/test/plugin/test_out_file.rb +36 -0
  60. data/test/plugin/test_out_forward.rb +279 -8
  61. data/test/plugin/test_out_roundrobin.rb +1 -0
  62. data/test/plugin/test_out_stdout.rb +1 -0
  63. data/test/plugin/test_out_stream.rb +1 -1
  64. data/test/test_buffer.rb +530 -0
  65. data/test/test_config.rb +1 -1
  66. data/test/test_configdsl.rb +1 -1
  67. data/test/test_formatter.rb +223 -0
  68. data/test/test_match.rb +1 -2
  69. data/test/test_mixin.rb +74 -2
  70. data/test/test_parser.rb +7 -1
  71. metadata +88 -35
  72. data/lib/fluent/plugin/buf_zfile.rb +0 -75
  73. data/spec/config/config_parser_spec.rb +0 -314
  74. data/spec/config/configurable_spec.rb +0 -524
  75. data/spec/config/configure_proxy_spec.rb +0 -96
  76. data/spec/config/dsl_spec.rb +0 -239
  77. data/spec/config/helper.rb +0 -49
  78. data/spec/config/literal_parser_spec.rb +0 -222
  79. data/spec/config/section_spec.rb +0 -97
  80. data/spec/config/system_config_spec.rb +0 -49
  81. data/spec/spec_helper.rb +0 -60
@@ -0,0 +1,530 @@
1
+ require 'helper'
2
+ require 'fluent/configurable'
3
+ require 'fluent/config/element'
4
+ require 'fluent/config/section'
5
+
6
+ module ConfigurableSpec
7
+ class Base1
8
+ include Fluent::Configurable
9
+
10
+ config_param :node, :string, :default => "node"
11
+ config_param :flag1, :bool, :default => false
12
+ config_param :flag2, :bool, :default => true
13
+
14
+ config_param :name1, :string
15
+ config_param :name2, :string
16
+ config_param :name3, :string, :default => "base1"
17
+ config_param :name4, :string, :default => "base1"
18
+
19
+ def get_all
20
+ [@node, @flag1, @flag2, @name1, @name2, @name3, @name4]
21
+ end
22
+ end
23
+
24
+ class Base2 < Base1
25
+ config_set_default :name2, "base2"
26
+ config_set_default :name4, "base2"
27
+ config_param :name5, :string
28
+ config_param :name6, :string, :default => "base2"
29
+
30
+ def get_all
31
+ ary = super
32
+ ary + [@name5, @name6]
33
+ end
34
+ end
35
+
36
+ class Base3 < Base2
37
+ config_section :node do
38
+ config_param :name, :string, :default => "node"
39
+ config_param :type, :string
40
+ end
41
+ config_section :branch, required: true, multi: true do
42
+ config_argument :name, :string
43
+ config_param :size, :integer, default: 10
44
+ config_section :leaf, required: false, multi: true do
45
+ config_param :weight, :integer
46
+ config_section :worm, param_name: 'worms', multi: true do
47
+ config_param :type, :string, default: 'ladybird'
48
+ end
49
+ end
50
+ end
51
+
52
+ def get_all
53
+ ary = super
54
+ ary + [@branch]
55
+ end
56
+ end
57
+
58
+ class Base4 < Base2
59
+ config_section :node, param_name: :nodes do
60
+ config_argument :num, :integer
61
+ config_param :name, :string, :default => "node"
62
+ config_param :type, :string, :default => "b4"
63
+ end
64
+ config_section :description1, required: false, multi: false do
65
+ config_argument :note, :string, default: "desc1"
66
+ config_param :text, :string
67
+ end
68
+ config_section :description2, required: true, multi: false do
69
+ config_argument :note, :string, default: "desc2"
70
+ config_param :text, :string
71
+ end
72
+ config_section :description3, required: true, multi: true do
73
+ config_argument :note, default: "desc3" do |val|
74
+ "desc3: #{val}"
75
+ end
76
+ config_param :text, :string
77
+ end
78
+
79
+ def get_all
80
+ ary = super
81
+ ary + [@nodes, @description1, @description2, @description3]
82
+ end
83
+ end
84
+
85
+ class Example0
86
+ include Fluent::Configurable
87
+
88
+ config_param :stringvalue, :string
89
+ config_param :boolvalue, :bool
90
+ config_param :integervalue, :integer
91
+ config_param :sizevalue, :size
92
+ config_param :timevalue, :time
93
+ config_param :floatvalue, :float
94
+ config_param :hashvalue, :hash
95
+ config_param :arrayvalue, :array
96
+ end
97
+
98
+ class Example1
99
+ include Fluent::Configurable
100
+
101
+ config_param :name, :string, alias: :fullname
102
+ config_param :bool, :bool, alias: :flag
103
+ config_section :detail, required: true, multi: false, alias: "information" do
104
+ config_param :address, :string
105
+ end
106
+
107
+ def get_all
108
+ [@name, @detail]
109
+ end
110
+ end
111
+ end
112
+
113
+ module Fluent::Config
114
+ class TestConfigurable < ::Test::Unit::TestCase
115
+ sub_test_case 'class defined without config_section' do
116
+ sub_test_case '#initialize' do
117
+ test 'create instance methods and default values by config_param and config_set_default' do
118
+ obj1 = ConfigurableSpec::Base1.new
119
+ assert_equal("node", obj1.node)
120
+ assert_false(obj1.flag1)
121
+ assert_true(obj1.flag2)
122
+ assert_nil(obj1.name1)
123
+ assert_nil(obj1.name2)
124
+ assert_equal("base1", obj1.name3)
125
+ assert_equal("base1", obj1.name4)
126
+ end
127
+
128
+ test 'create instance methods and default values overwritten by sub class definition' do
129
+ obj2 = ConfigurableSpec::Base2.new
130
+ assert_equal("node", obj2.node)
131
+ assert_false(obj2.flag1)
132
+ assert_true(obj2.flag2)
133
+ assert_nil(obj2.name1)
134
+ assert_equal("base2", obj2.name2)
135
+ assert_equal("base1", obj2.name3)
136
+ assert_equal("base2", obj2.name4)
137
+ assert_nil(obj2.name5)
138
+ assert_equal("base2", obj2.name6)
139
+ end
140
+ end
141
+
142
+ sub_test_case '#configure' do
143
+ test 'returns configurable object itself' do
144
+ b2 = ConfigurableSpec::Base2.new
145
+ assert_instance_of(ConfigurableSpec::Base2, b2.configure({"name1" => "t1", "name5" => "t5"}))
146
+ end
147
+
148
+ test 'raise errors without any specifications for param without defaults' do
149
+ b2 = ConfigurableSpec::Base2.new
150
+ assert_raise(Fluent::ConfigError) { b2.configure({}) }
151
+ assert_raise(Fluent::ConfigError) { b2.configure({"name1" => "t1"}) }
152
+ assert_raise(Fluent::ConfigError) { b2.configure({"name5" => "t5"}) }
153
+ assert_nothing_raised { b2.configure({"name1" => "t1", "name5" => "t5"}) }
154
+
155
+ assert_equal(["node", false, true, "t1", "base2", "base1", "base2", "t5", "base2"], b2.get_all)
156
+ end
157
+
158
+ test 'can configure bool values' do
159
+ b2a = ConfigurableSpec::Base2.new
160
+ assert_nothing_raised { b2a.configure({"flag1" => "true", "flag2" => "yes", "name1" => "t1", "name5" => "t5"}) }
161
+ assert_true(b2a.flag1)
162
+ assert_true(b2a.flag2)
163
+
164
+ b2b = ConfigurableSpec::Base2.new
165
+ assert_nothing_raised { b2b.configure({"flag1" => false, "flag2" => "no", "name1" => "t1", "name5" => "t5"}) }
166
+ assert_false(b2b.flag1)
167
+ assert_false(b2b.flag2)
168
+ end
169
+
170
+ test 'overwrites values of defaults' do
171
+ b2 = ConfigurableSpec::Base2.new
172
+ b2.configure({"name1" => "t1", "name2" => "t2", "name3" => "t3", "name4" => "t4", "name5" => "t5"})
173
+ assert_equal("t1", b2.name1)
174
+ assert_equal("t2", b2.name2)
175
+ assert_equal("t3", b2.name3)
176
+ assert_equal("t4", b2.name4)
177
+ assert_equal("t5", b2.name5)
178
+ assert_equal("base2", b2.name6)
179
+
180
+ assert_equal(["node", false, true, "t1", "t2", "t3", "t4", "t5", "base2"], b2.get_all)
181
+ end
182
+ end
183
+ end
184
+
185
+ sub_test_case 'class defined with config_section' do
186
+ sub_test_case '#initialize' do
187
+ test 'create instance methods and default values as nil for params from config_section specified as non-multi' do
188
+ b4 = ConfigurableSpec::Base4.new
189
+ assert_nil(b4.description1)
190
+ assert_nil(b4.description2)
191
+ end
192
+
193
+ test 'create instance methods and default values as [] for params from config_section specified as multi' do
194
+ b4 = ConfigurableSpec::Base4.new
195
+ assert_equal([], b4.description3)
196
+ end
197
+
198
+ test 'overwrite base class definition by config_section of sub class definition' do
199
+ b3 = ConfigurableSpec::Base3.new
200
+ assert_equal([], b3.node)
201
+ end
202
+
203
+ test 'create instance methods and default values by param_name' do
204
+ b4 = ConfigurableSpec::Base4.new
205
+ assert_equal([], b4.nodes)
206
+ assert_equal("node", b4.node)
207
+ end
208
+
209
+ test 'create non-required and multi without any specifications' do
210
+ b3 = ConfigurableSpec::Base3.new
211
+ assert_false(b3.class.merged_configure_proxy.sections[:node].required?)
212
+ assert_true(b3.class.merged_configure_proxy.sections[:node].multi?)
213
+ end
214
+ end
215
+
216
+ sub_test_case '#configure' do
217
+ def e(name, arg = '', attrs = {}, elements = [])
218
+ attrs_str_keys = {}
219
+ attrs.each{|key, value| attrs_str_keys[key.to_s] = value }
220
+ Fluent::Config::Element.new(name, arg, attrs_str_keys, elements)
221
+ end
222
+
223
+ BASE_ATTRS = {
224
+ "name1" => "1", "name2" => "2", "name3" => "3",
225
+ "name4" => "4", "name5" => "5", "name6" => "6",
226
+ }
227
+ test 'checks required subsections' do
228
+ b3 = ConfigurableSpec::Base3.new
229
+ # branch sections required
230
+ assert_raise(Fluent::ConfigError) { b3.configure(e('ROOT', '', BASE_ATTRS, [])) }
231
+
232
+ # branch argument required
233
+ msg = "'<branch ARG>' section requires argument, in section branch"
234
+ #expect{ b3.configure(e('ROOT', '', BASE_ATTRS, [e('branch', '')])) }.to raise_error(Fluent::ConfigError, msg)
235
+ assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(e('ROOT', '', BASE_ATTRS, [e('branch', '')])) }
236
+
237
+ # leaf is not required
238
+ assert_nothing_raised { b3.configure(e('ROOT', '', BASE_ATTRS, [e('branch', 'branch_name')])) }
239
+
240
+ # leaf weight required
241
+ msg = "'weight' parameter is required, in section branch > leaf"
242
+ branch1 = e('branch', 'branch_name', {size: 1}, [e('leaf', '10', {weight: 1})])
243
+ assert_nothing_raised { b3.configure(e('ROOT', '', BASE_ATTRS, [branch1])) }
244
+ branch2 = e('branch', 'branch_name', {size: 1}, [e('leaf', '20')])
245
+ assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(e('ROOT', '', BASE_ATTRS, [branch1, branch2])) }
246
+ branch3 = e('branch', 'branch_name', {size: 1}, [e('leaf', '10', {weight: 3}), e('leaf', '20')])
247
+ assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(e('ROOT', '', BASE_ATTRS, [branch3])) }
248
+
249
+ ### worm not required
250
+
251
+ b4 = ConfigurableSpec::Base4.new
252
+
253
+ d1 = e('description1', '', {text:"d1"})
254
+ d2 = e('description2', '', {text:"d2"})
255
+ d3 = e('description3', '', {text:"d3"})
256
+ assert_nothing_raised { b4.configure(e('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup])) }
257
+
258
+ # description1 cannot be specified 2 or more
259
+ msg = "'<description1>' section cannot be written twice or more"
260
+ assert_raise(Fluent::ConfigError.new(msg)) { b4.configure(e('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d1.dup, d3.dup])) }
261
+
262
+ # description2 cannot be specified 2 or more
263
+ msg = "'<description2>' section cannot be written twice or more"
264
+ assert_raise(Fluent::ConfigError.new(msg)) { b4.configure(e('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup, d2.dup])) }
265
+
266
+ # description3 can be specified 2 or more
267
+ assert_nothing_raised { b4.configure(e('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup, d3.dup])) }
268
+ end
269
+
270
+ test 'constructs confuguration object tree for Base3' do
271
+ conf = e(
272
+ 'ROOT',
273
+ '',
274
+ BASE_ATTRS,
275
+ [
276
+ e('node', '', {type:"1"}), e('node', '', {name:"node2",type:"2"}),
277
+ e('branch', 'b1.*', {}, []),
278
+ e('branch',
279
+ 'b2.*',
280
+ {size: 5},
281
+ [
282
+ e('leaf', 'THIS IS IGNORED', {weight: 55}, []),
283
+ e('leaf', 'THIS IS IGNORED', {weight: 50}, [ e('worm', '', {}) ]),
284
+ e('leaf', 'THIS IS IGNORED', {weight: 50}, [ e('worm', '', {type:"w1"}), e('worm', '', {type:"w2"}) ]),
285
+ ]
286
+ ),
287
+ e('branch',
288
+ 'b3.*',
289
+ {size: "503"},
290
+ [
291
+ e('leaf', 'THIS IS IGNORED', {weight: 55}, []),
292
+ ]
293
+ )
294
+ ],
295
+ )
296
+ b3 = ConfigurableSpec::Base3.new.configure(conf)
297
+
298
+ assert_not_equal("node", b3.node) # overwritten
299
+
300
+ assert_equal("1", b3.name1)
301
+ assert_equal("2", b3.name2)
302
+ assert_equal("3", b3.name3)
303
+ assert_equal("4", b3.name4)
304
+ assert_equal("5", b3.name5)
305
+ assert_equal("6", b3.name6)
306
+
307
+ assert_instance_of(Array, b3.node)
308
+ assert_equal(2, b3.node.size)
309
+
310
+ assert_equal("node", b3.node[0].name)
311
+ assert_equal("1", b3.node[0].type)
312
+ assert_equal(b3.node[0].type, b3.node[0][:type])
313
+ assert_equal("node2", b3.node[1].name)
314
+ assert_equal("2", b3.node[1].type)
315
+ assert_equal(b3.node[1].type, b3.node[1][:type])
316
+
317
+ assert_instance_of(Array, b3.branch)
318
+ assert_equal(3, b3.branch.size)
319
+
320
+ assert_equal('b1.*', b3.branch[0].name)
321
+ assert_equal(10, b3.branch[0].size)
322
+ assert_equal([], b3.branch[0].leaf)
323
+
324
+ assert_equal('b2.*', b3.branch[1].name)
325
+ assert_equal(5, b3.branch[1].size)
326
+ assert_equal(3, b3.branch[1].leaf.size)
327
+ assert_equal(b3.branch[1].leaf, b3.branch[1][:leaf])
328
+
329
+ assert_equal(55, b3.branch[1].leaf[0].weight)
330
+ assert_equal(0, b3.branch[1].leaf[0].worms.size)
331
+
332
+ assert_equal(50, b3.branch[1].leaf[1].weight)
333
+ assert_equal(1, b3.branch[1].leaf[1].worms.size)
334
+ assert_equal("ladybird", b3.branch[1].leaf[1].worms[0].type)
335
+
336
+ assert_equal(50, b3.branch[1].leaf[2].weight)
337
+ assert_equal(2, b3.branch[1].leaf[2].worms.size)
338
+ assert_equal("w1", b3.branch[1].leaf[2].worms[0].type)
339
+ assert_equal("w2", b3.branch[1].leaf[2].worms[1].type)
340
+
341
+ assert_equal('b3.*', b3.branch[2].name)
342
+ assert_equal(503, b3.branch[2].size)
343
+ assert_equal(1, b3.branch[2].leaf.size)
344
+ assert_equal(55, b3.branch[2].leaf[0].weight)
345
+ end
346
+
347
+ test 'constructs confuguration object tree for Base4' do
348
+ conf = e(
349
+ 'ROOT',
350
+ '',
351
+ BASE_ATTRS,
352
+ [
353
+ e('node', '1', {type:"1"}), e('node', '2', {name:"node2"}),
354
+ e('description3', '', {text:"dddd3-1"}),
355
+ e('description2', 'd-2', {text:"dddd2"}),
356
+ e('description1', '', {text:"dddd1"}),
357
+ e('description3', 'd-3', {text:"dddd3-2"}),
358
+ e('description3', 'd-3a', {text:"dddd3-3"}),
359
+ e('node', '4', {type:"four"}),
360
+ ],
361
+ )
362
+ b4 = ConfigurableSpec::Base4.new.configure(conf)
363
+
364
+ assert_equal("node", b4.node)
365
+
366
+ assert_equal("1", b4.name1)
367
+ assert_equal("2", b4.name2)
368
+ assert_equal("3", b4.name3)
369
+ assert_equal("4", b4.name4)
370
+ assert_equal("5", b4.name5)
371
+ assert_equal("6", b4.name6)
372
+
373
+ assert_instance_of(Array, b4.nodes)
374
+ assert_equal(3, b4.nodes.size)
375
+ assert_equal(1, b4.nodes[0].num)
376
+ assert_equal("node", b4.nodes[0].name)
377
+ assert_equal("1", b4.nodes[0].type)
378
+ assert_equal(2, b4.nodes[1].num)
379
+ assert_equal("node2", b4.nodes[1].name)
380
+ assert_equal("b4", b4.nodes[1].type)
381
+ assert_equal(4, b4.nodes[2].num)
382
+ assert_equal("node", b4.nodes[2].name)
383
+ assert_equal("four", b4.nodes[2].type)
384
+
385
+ # e('description3', '', {text:"dddd3-1"}),
386
+ # e('description3', 'd-3', {text:"dddd3-2"}),
387
+ # e('description3', 'd-3a', {text:"dddd3-3"}),
388
+
389
+ # NoMethodError: undefined method `class' for <Fluent::Config::Section {...}>:Fluent::Config::Section occurred. Should we add class method to Section?
390
+ #assert_equal('Fluent::Config::Section', b4.description1.class.name)
391
+ assert_equal("desc1", b4.description1.note)
392
+ assert_equal("dddd1", b4.description1.text)
393
+
394
+ # same with assert_equal('Fluent::Config::Section', b4.description1)
395
+ #assert_equal('Fluent::Config::Section', b4.description2)
396
+ assert_equal("d-2", b4.description2.note)
397
+ assert_equal("dddd2", b4.description2.text)
398
+
399
+ assert_instance_of(Array, b4.description3)
400
+ assert_equal(3, b4.description3.size)
401
+ assert_equal("desc3", b4.description3[0].note)
402
+ assert_equal("dddd3-1", b4.description3[0].text)
403
+ assert_equal('desc3: d-3', b4.description3[1].note)
404
+ assert_equal('dddd3-2', b4.description3[1].text)
405
+ assert_equal('desc3: d-3a', b4.description3[2].note)
406
+ assert_equal('dddd3-3', b4.description3[2].text)
407
+ end
408
+
409
+ test 'checks missing of specifications' do
410
+ conf0 = e('ROOT', '', {}, [])
411
+ ex01 = ConfigurableSpec::Example0.new
412
+ assert_raise(Fluent::ConfigError) { ex01.configure(conf0) }
413
+
414
+ complete = {
415
+ "stringvalue" => "s1", "boolvalue" => "yes", "integervalue" => "10",
416
+ "sizevalue" => "10m", "timevalue" => "100s", "floatvalue" => "1.001",
417
+ "hashvalue" => '{"foo":1, "bar":2}',
418
+ "arrayvalue" => '[1,"ichi"]',
419
+ }
420
+
421
+ checker = lambda { |conf| ConfigurableSpec::Example0.new.configure(conf) }
422
+
423
+ assert_nothing_raised { checker.call(complete) }
424
+ assert_raise(Fluent::ConfigError) { checker.call(complete.reject{|k,v| k == "stringvalue" }) }
425
+ assert_raise(Fluent::ConfigError) { checker.call(complete.reject{|k,v| k == "boolvalue" }) }
426
+ assert_raise(Fluent::ConfigError) { checker.call(complete.reject{|k,v| k == "integervalue"}) }
427
+ assert_raise(Fluent::ConfigError) { checker.call(complete.reject{|k,v| k == "sizevalue" }) }
428
+ assert_raise(Fluent::ConfigError) { checker.call(complete.reject{|k,v| k == "timevalue" }) }
429
+ assert_raise(Fluent::ConfigError) { checker.call(complete.reject{|k,v| k == "floatvalue" }) }
430
+ assert_raise(Fluent::ConfigError) { checker.call(complete.reject{|k,v| k == "hashvalue" }) }
431
+ assert_raise(Fluent::ConfigError) { checker.call(complete.reject{|k,v| k == "arrayvalue" }) }
432
+ end
433
+
434
+ test 'accepts configuration values as string representation' do
435
+ conf = {
436
+ "stringvalue" => "s1", "boolvalue" => "yes", "integervalue" => "10",
437
+ "sizevalue" => "10m", "timevalue" => "10m", "floatvalue" => "1.001",
438
+ "hashvalue" => '{"foo":1, "bar":2}',
439
+ "arrayvalue" => '[1,"ichi"]',
440
+ }
441
+ ex = ConfigurableSpec::Example0.new.configure(conf)
442
+ assert_equal("s1", ex.stringvalue)
443
+ assert_true(ex.boolvalue)
444
+ assert_equal(10, ex.integervalue)
445
+ assert_equal(10 * 1024 * 1024, ex.sizevalue)
446
+ assert_equal(10 * 60, ex.timevalue)
447
+ assert_equal(1.001, ex.floatvalue)
448
+ assert_equal({"foo" => 1, "bar" => 2}, ex.hashvalue)
449
+ assert_equal([1, "ichi"], ex.arrayvalue)
450
+ end
451
+
452
+ test 'accepts configuration values as ruby value representation (especially for DSL)' do
453
+ conf = {
454
+ "stringvalue" => "s1", "boolvalue" => true, "integervalue" => 10,
455
+ "sizevalue" => 10 * 1024 * 1024, "timevalue" => 10 * 60, "floatvalue" => 1.001,
456
+ "hashvalue" => {"foo" => 1, "bar" => 2},
457
+ "arrayvalue" => [1,"ichi"],
458
+ }
459
+ ex = ConfigurableSpec::Example0.new.configure(conf)
460
+ assert_equal("s1", ex.stringvalue)
461
+ assert_true(ex.boolvalue)
462
+ assert_equal(10, ex.integervalue)
463
+ assert_equal(10 * 1024 * 1024, ex.sizevalue)
464
+ assert_equal(10 * 60, ex.timevalue)
465
+ assert_equal(1.001, ex.floatvalue)
466
+ assert_equal({"foo" => 1, "bar" => 2}, ex.hashvalue)
467
+ assert_equal([1, "ichi"], ex.arrayvalue)
468
+ end
469
+
470
+ test 'gets both of true(yes) and false(no) for bool value parameter' do
471
+ conf = {
472
+ "stringvalue" => "s1", "integervalue" => 10,
473
+ "sizevalue" => 10 * 1024 * 1024, "timevalue" => 10 * 60, "floatvalue" => 1.001,
474
+ "hashvalue" => {"foo" => 1, "bar" => 2},
475
+ "arrayvalue" => [1,"ichi"],
476
+ }
477
+ ex0 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => "true"}))
478
+ assert_true(ex0.boolvalue)
479
+
480
+ ex1 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => "yes"}))
481
+ assert_true(ex1.boolvalue)
482
+
483
+ ex2 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => true}))
484
+ assert_true(ex2.boolvalue)
485
+
486
+ ex3 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => "false"}))
487
+ assert_false(ex3.boolvalue)
488
+
489
+ ex4 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => "no"}))
490
+ assert_false(ex4.boolvalue)
491
+
492
+ ex5 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => false}))
493
+ assert_false(ex5.boolvalue)
494
+ end
495
+ end
496
+ end
497
+
498
+ sub_test_case 'class defined with config_param/config_section having :alias' do
499
+ sub_test_case '#initialize' do
500
+ test 'does not create methods for alias' do
501
+ ex1 = ConfigurableSpec::Example1.new
502
+ assert_nothing_raised { ex1.name }
503
+ assert_raise(NoMethodError) { ex1.fullname }
504
+ assert_nothing_raised { ex1.bool }
505
+ assert_raise(NoMethodError) { ex1.flag }
506
+ assert_nothing_raised { ex1.detail }
507
+ assert_raise(NoMethodError) { ex1.information}
508
+ end
509
+ end
510
+
511
+ sub_test_case '#configure' do
512
+ def e(name, arg = '', attrs = {}, elements = [])
513
+ attrs_str_keys = {}
514
+ attrs.each{|key, value| attrs_str_keys[key.to_s] = value }
515
+ Fluent::Config::Element.new(name, arg, attrs_str_keys, elements)
516
+ end
517
+
518
+ test 'provides accessible data for alias attribute keys' do
519
+ ex1 = ConfigurableSpec::Example1.new
520
+ ex1.configure(e('ROOT', '', {"fullname" => "foo bar", "bool" => false}, [e('information', '', {"address" => "Mountain View 0"})]))
521
+ assert_equal("foo bar", ex1.name)
522
+ assert_not_nil(ex1.bool)
523
+ assert_false(ex1.bool)
524
+ assert_not_nil(ex1.detail)
525
+ assert_equal("Mountain View 0", ex1.detail.address)
526
+ end
527
+ end
528
+ end
529
+ end
530
+ end