fluentd 0.10.62 → 0.12.0.pre.1

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