fluentd 0.14.0 → 0.14.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/example/copy_roundrobin.conf +39 -0
  3. data/example/filter_stdout.conf +5 -5
  4. data/example/in_forward.conf +2 -2
  5. data/example/in_http.conf +2 -2
  6. data/example/in_syslog.conf +2 -2
  7. data/example/in_tail.conf +2 -2
  8. data/example/in_tcp.conf +2 -2
  9. data/example/in_udp.conf +2 -2
  10. data/example/out_buffered_null.conf +32 -0
  11. data/example/out_copy.conf +4 -4
  12. data/example/out_file.conf +2 -2
  13. data/example/out_forward.conf +2 -2
  14. data/example/v0_12_filter.conf +8 -8
  15. data/fluentd.gemspec +1 -1
  16. data/lib/fluent/command/fluentd.rb +6 -1
  17. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  18. data/lib/fluent/compat/input.rb +1 -0
  19. data/lib/fluent/compat/output.rb +1 -0
  20. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  21. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  22. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  23. data/lib/fluent/compat/type_converter.rb +90 -0
  24. data/lib/fluent/config/configure_proxy.rb +24 -4
  25. data/lib/fluent/config/dsl.rb +18 -1
  26. data/lib/fluent/config/v1_parser.rb +3 -2
  27. data/lib/fluent/configurable.rb +1 -1
  28. data/lib/fluent/event.rb +37 -9
  29. data/lib/fluent/mixin.rb +12 -286
  30. data/lib/fluent/plugin/buffer.rb +2 -2
  31. data/lib/fluent/plugin/in_dummy.rb +5 -1
  32. data/lib/fluent/plugin/in_gc_stat.rb +7 -37
  33. data/lib/fluent/plugin/in_http.rb +2 -0
  34. data/lib/fluent/plugin/{in_stream.rb → in_unix.rb} +0 -0
  35. data/lib/fluent/plugin/out_buffered_stdout.rb +60 -0
  36. data/lib/fluent/plugin/out_copy.rb +8 -51
  37. data/lib/fluent/plugin/out_null.rb +5 -5
  38. data/lib/fluent/plugin/out_relabel.rb +5 -5
  39. data/lib/fluent/plugin/out_roundrobin.rb +13 -40
  40. data/lib/fluent/plugin/output.rb +9 -0
  41. data/lib/fluent/plugin_helper.rb +2 -0
  42. data/lib/fluent/plugin_helper/formatter.rb +138 -0
  43. data/lib/fluent/plugin_helper/inject.rb +112 -0
  44. data/lib/fluent/plugin_helper/parser.rb +138 -0
  45. data/lib/fluent/plugin_helper/storage.rb +64 -50
  46. data/lib/fluent/process.rb +6 -1
  47. data/lib/fluent/registry.rb +1 -1
  48. data/lib/fluent/supervisor.rb +20 -2
  49. data/lib/fluent/test.rb +30 -5
  50. data/lib/fluent/test/base.rb +2 -66
  51. data/lib/fluent/test/driver/base.rb +3 -0
  52. data/lib/fluent/test/driver/base_owned.rb +106 -0
  53. data/lib/fluent/test/driver/formatter.rb +30 -0
  54. data/lib/fluent/test/driver/multi_output.rb +52 -0
  55. data/lib/fluent/test/driver/owner.rb +32 -0
  56. data/lib/fluent/test/driver/parser.rb +30 -0
  57. data/lib/fluent/test/helpers.rb +54 -0
  58. data/lib/fluent/test/log.rb +73 -0
  59. data/lib/fluent/time.rb +71 -0
  60. data/lib/fluent/version.rb +1 -1
  61. data/test/compat/test_parser.rb +82 -0
  62. data/test/config/test_configure_proxy.rb +15 -0
  63. data/test/config/test_dsl.rb +180 -2
  64. data/test/helper.rb +2 -24
  65. data/test/plugin/test_in_gc_stat.rb +6 -6
  66. data/test/plugin/test_in_http.rb +49 -32
  67. data/test/plugin/{test_in_stream.rb → test_in_unix.rb} +1 -1
  68. data/test/plugin/test_out_buffered_stdout.rb +108 -0
  69. data/test/plugin/test_out_copy.rb +88 -127
  70. data/test/plugin/test_out_null.rb +29 -0
  71. data/test/plugin/test_out_relabel.rb +28 -0
  72. data/test/plugin/test_out_roundrobin.rb +35 -29
  73. data/test/plugin/test_out_stdout.rb +4 -4
  74. data/test/plugin/test_output_as_buffered.rb +51 -0
  75. data/test/plugin/test_output_as_buffered_secondary.rb +13 -0
  76. data/test/plugin/test_parser_apache.rb +38 -0
  77. data/test/plugin/test_parser_apache2.rb +38 -0
  78. data/test/plugin/test_parser_apache_error.rb +40 -0
  79. data/test/plugin/test_parser_base.rb +32 -0
  80. data/test/plugin/test_parser_csv.rb +94 -0
  81. data/test/plugin/test_parser_json.rb +107 -0
  82. data/test/plugin/test_parser_labeled_tsv.rb +129 -0
  83. data/test/plugin/test_parser_multiline.rb +100 -0
  84. data/test/plugin/test_parser_nginx.rb +42 -0
  85. data/test/plugin/test_parser_none.rb +53 -0
  86. data/test/plugin/test_parser_regexp.rb +110 -0
  87. data/test/plugin/test_parser_syslog.rb +66 -0
  88. data/test/plugin/test_parser_time.rb +46 -0
  89. data/test/plugin/test_parser_tsv.rb +125 -0
  90. data/test/plugin_helper/test_child_process.rb +11 -2
  91. data/test/plugin_helper/test_formatter.rb +212 -0
  92. data/test/plugin_helper/test_inject.rb +388 -0
  93. data/test/plugin_helper/test_parser.rb +223 -0
  94. data/test/plugin_helper/test_retry_state.rb +40 -40
  95. data/test/plugin_helper/test_storage.rb +77 -10
  96. data/test/scripts/fluent/plugin/out_test.rb +22 -17
  97. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  98. data/test/test_event.rb +57 -0
  99. data/test/test_formatter.rb +0 -178
  100. data/test/test_output.rb +2 -152
  101. data/test/test_root_agent.rb +3 -2
  102. data/test/test_supervisor.rb +93 -26
  103. data/test/test_time_formatter.rb +186 -0
  104. metadata +69 -7
  105. data/test/test_parser.rb +0 -1087
@@ -0,0 +1,32 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/plugin/base'
18
+ require 'fluent/plugin_id'
19
+ require 'fluent/log'
20
+ require 'fluent/plugin_helper'
21
+
22
+ module Fluent
23
+ module Test
24
+ module Driver
25
+ class Owner < Fluent::Plugin::Base
26
+ include PluginId
27
+ include PluginLoggerMixin
28
+ include PluginHelper::Mixin
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,30 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/test/driver/base_owned'
18
+
19
+ module Fluent
20
+ module Test
21
+ module Driver
22
+ class Parser < BaseOwned
23
+ def initialize(klass, **kwargs, &block)
24
+ super
25
+ @section_name = "parse"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,54 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/config/element'
18
+ require 'fluent/msgpack_factory'
19
+ require 'fluent/time'
20
+
21
+ module Fluent
22
+ module Test
23
+ module Helpers
24
+ def config_element(name = 'test', argument = '', params = {}, elements = [])
25
+ Fluent::Config::Element.new(name, argument, params, elements)
26
+ end
27
+
28
+ def event_time(str=nil, format: nil)
29
+ if str
30
+ if format
31
+ Fluent::EventTime.from_time(Time.strptime(str, format))
32
+ else
33
+ Fluent::EventTime.parse(str)
34
+ end
35
+ else
36
+ Fluent::EventTime.now
37
+ end
38
+ end
39
+
40
+ def msgpack(type)
41
+ case type
42
+ when :factory
43
+ Fluent::MessagePackFactory.factory
44
+ when :packer
45
+ Fluent::MessagePackFactory.packer
46
+ when :unpacker
47
+ Fluent::MessagePackFactory.unpacker
48
+ else
49
+ raise ArgumentError, "unknown msgpack object type '#{type}'"
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,73 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'serverengine'
18
+ require 'fluent/log'
19
+
20
+ module Fluent
21
+ module Test
22
+ class DummyLogDevice
23
+ attr_reader :logs
24
+
25
+ def initialize
26
+ @logs = []
27
+ end
28
+
29
+ def reset
30
+ @logs = []
31
+ end
32
+
33
+ def tty?
34
+ false
35
+ end
36
+
37
+ def puts(*args)
38
+ args.each{ |arg| write(arg + "\n") }
39
+ end
40
+
41
+ def write(message)
42
+ @logs.push message
43
+ end
44
+
45
+ def flush
46
+ true
47
+ end
48
+
49
+ def close
50
+ true
51
+ end
52
+ end
53
+
54
+ class TestLogger < Fluent::PluginLogger
55
+ def initialize
56
+ @logdev = DummyLogDevice.new
57
+ dl_opts = {}
58
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::INFO
59
+ logger = ServerEngine::DaemonLogger.new(@logdev, dl_opts)
60
+ log = Fluent::Log.new(logger)
61
+ super(log)
62
+ end
63
+
64
+ def reset
65
+ @logdev.reset
66
+ end
67
+
68
+ def logs
69
+ @logdev.logs
70
+ end
71
+ end
72
+ end
73
+ end
@@ -16,6 +16,7 @@
16
16
 
17
17
  require 'time'
18
18
  require 'msgpack'
19
+ require 'fluent/timezone'
19
20
 
20
21
  module Fluent
21
22
  class EventTime
@@ -101,4 +102,74 @@ module Fluent
101
102
  @sec.send(name, *args, &block)
102
103
  end
103
104
  end
105
+
106
+ class TimeFormatter
107
+ def initialize(format, localtime, timezone = nil)
108
+ @tc1 = 0
109
+ @tc1_str = nil
110
+ @tc2 = 0
111
+ @tc2_str = nil
112
+
113
+ if format && format =~ /(^|[^%])(%%)*%L|(^|[^%])(%%)*%\d*N/
114
+ define_singleton_method(:format, method(:format_with_subsec))
115
+ define_singleton_method(:call, method(:format_with_subsec))
116
+ else
117
+ define_singleton_method(:format, method(:format_without_subsec))
118
+ define_singleton_method(:call, method(:format_with_subsec))
119
+ end
120
+
121
+ formatter = Fluent::Timezone.formatter(timezone, format)
122
+ @format_nocache = case
123
+ when formatter then formatter
124
+ when format && localtime then ->(time){ Time.at(time).strftime(format) }
125
+ when format then ->(time){ Time.at(time).utc.strftime(format) }
126
+ when localtime then ->(time){ Time.at(time).iso8601 }
127
+ else ->(time){ Time.at(time).utc.iso8601 }
128
+ end
129
+ end
130
+
131
+ def format_without_subsec(time)
132
+ if @tc1 == time
133
+ return @tc1_str
134
+ elsif @tc2 == time
135
+ return @tc2_str
136
+ else
137
+ str = format_nocache(time)
138
+ if @tc1 < @tc2
139
+ @tc1 = time
140
+ @tc1_str = str
141
+ else
142
+ @tc2 = time
143
+ @tc2_str = str
144
+ end
145
+ return str
146
+ end
147
+ end
148
+
149
+ def format_with_subsec(time)
150
+ if Fluent::EventTime.eq?(@tc1, time)
151
+ return @tc1_str
152
+ elsif Fluent::EventTime.eq?(@tc2, time)
153
+ return @tc2_str
154
+ else
155
+ str = format_nocache(time)
156
+ if @tc1 < @tc2
157
+ @tc1 = time
158
+ @tc1_str = str
159
+ else
160
+ @tc2 = time
161
+ @tc2_str = str
162
+ end
163
+ return str
164
+ end
165
+ end
166
+
167
+ ## Dynamically defined in #initialize
168
+ # def format(time)
169
+ # end
170
+
171
+ def format_nocache(time)
172
+ @format_nocache.call(time)
173
+ end
174
+ end
104
175
  end
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '0.14.0'
19
+ VERSION = '0.14.1'
20
20
 
21
21
  end
@@ -0,0 +1,82 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin/parser'
3
+
4
+ class TextParserTest < ::Test::Unit::TestCase
5
+ def setup
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ class MultiEventTestParser < ::Fluent::Parser
10
+ include Fluent::Configurable
11
+
12
+ def parse(text)
13
+ 2.times { |i|
14
+ record = {}
15
+ record['message'] = text
16
+ record['number'] = i
17
+ yield Fluent::Engine.now, record
18
+ }
19
+ end
20
+ end
21
+
22
+ Fluent::TextParser.register_template('multi_event_test', Proc.new { MultiEventTestParser.new })
23
+
24
+ def test_lookup_unknown_format
25
+ assert_raise Fluent::ConfigError do
26
+ Fluent::Plugin.new_parser('unknown')
27
+ end
28
+ end
29
+
30
+ data('register_formatter' => 'known', 'register_template' => 'known_old')
31
+ def test_lookup_known_parser(data)
32
+ $LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'scripts'))
33
+ assert_nothing_raised Fluent::ConfigError do
34
+ Fluent::Plugin.new_parser(data)
35
+ end
36
+ $LOAD_PATH.shift
37
+ end
38
+
39
+ def test_parse_with_return
40
+ parser = Fluent::TextParser.new
41
+ parser.configure('format' => 'none')
42
+ _time, record = parser.parse('log message!')
43
+ assert_equal({'message' => 'log message!'}, record)
44
+ end
45
+
46
+ def test_parse_with_block
47
+ parser = Fluent::TextParser.new
48
+ parser.configure('format' => 'none')
49
+ parser.parse('log message!') { |time, record|
50
+ assert_equal({'message' => 'log message!'}, record)
51
+ }
52
+ end
53
+
54
+ def test_multi_event_parser
55
+ parser = Fluent::TextParser.new
56
+ parser.configure('format' => 'multi_event_test')
57
+ i = 0
58
+ parser.parse('log message!') { |time, record|
59
+ assert_equal('log message!', record['message'])
60
+ assert_equal(i, record['number'])
61
+ i += 1
62
+ }
63
+ end
64
+
65
+ def test_setting_estimate_current_event_value
66
+ p1 = Fluent::TextParser.new
67
+ assert_nil p1.estimate_current_event
68
+ assert_nil p1.parser
69
+
70
+ p1.configure('format' => 'none')
71
+ assert_equal true, p1.parser.estimate_current_event
72
+
73
+ p2 = Fluent::TextParser.new
74
+ assert_nil p2.estimate_current_event
75
+ assert_nil p2.parser
76
+
77
+ p2.estimate_current_event = false
78
+
79
+ p2.configure('format' => 'none')
80
+ assert_equal false, p2.parser.estimate_current_event
81
+ end
82
+ end
@@ -17,6 +17,7 @@ module Fluent::Config
17
17
  assert_equal(:section, proxy.name)
18
18
  assert_nil(proxy.param_name)
19
19
  assert_equal(:section, proxy.variable_name)
20
+ assert_false(proxy.root?)
20
21
  assert_nil(proxy.init)
21
22
  assert_nil(proxy.required)
22
23
  assert_false(proxy.required?)
@@ -94,6 +95,20 @@ module Fluent::Config
94
95
  assert_false(proxy.multi?)
95
96
  assert_equal :subsection, proxy.configured_in_section
96
97
  end
98
+
99
+ test "does overwrite name of proxy for root sections which are used for plugins" do
100
+ # latest plugin class shows actual plugin implementation
101
+ p1 = Fluent::Config::ConfigureProxy.new('Fluent::Plugin::MyP1'.to_sym, root: true, required: true, multi: false, type_lookup: @type_lookup)
102
+ p1.config_param :key1, :integer
103
+
104
+ p2 = Fluent::Config::ConfigureProxy.new('Fluent::Plugin::MyP2'.to_sym, root: true, required: true, multi: false, type_lookup: @type_lookup)
105
+ p2.config_param :key2, :string, default: "value2"
106
+
107
+ merged = p1.merge(p2)
108
+
109
+ assert_equal 'Fluent::Plugin::MyP2'.to_sym, merged.name
110
+ assert_true merged.root?
111
+ end
97
112
  end
98
113
 
99
114
  sub_test_case '#overwrite_defaults' do
@@ -2,6 +2,66 @@ require_relative '../helper'
2
2
  require 'fluent/config/element'
3
3
  require "fluent/config/dsl"
4
4
 
5
+ TMP_DIR = File.dirname(__FILE__) + "/tmp/config_dsl#{ENV['TEST_ENV_NUMBER']}"
6
+ def write_config(path, data)
7
+ FileUtils.mkdir_p(File.dirname(path))
8
+ File.open(path, "w") {|f| f.write data }
9
+ end
10
+
11
+ def prepare_config1
12
+ write_config "#{TMP_DIR}/config_test_1.conf", %[
13
+ k1 root_config
14
+ include dir/config_test_2.conf #
15
+ @include #{TMP_DIR}/config_test_4.conf
16
+ include file://#{TMP_DIR}/config_test_5.conf
17
+ @include config.d/*.conf
18
+ ]
19
+ write_config "#{TMP_DIR}/dir/config_test_2.conf", %[
20
+ k2 relative_path_include
21
+ @include ../config_test_3.conf
22
+ ]
23
+ write_config "#{TMP_DIR}/config_test_3.conf", %[
24
+ k3 relative_include_in_included_file
25
+ ]
26
+ write_config "#{TMP_DIR}/config_test_4.conf", %[
27
+ k4 absolute_path_include
28
+ ]
29
+ write_config "#{TMP_DIR}/config_test_5.conf", %[
30
+ k5 uri_include
31
+ ]
32
+ write_config "#{TMP_DIR}/config.d/config_test_6.conf", %[
33
+ k6 wildcard_include_1
34
+ <elem1 name>
35
+ include normal_parameter
36
+ </elem1>
37
+ ]
38
+ write_config "#{TMP_DIR}/config.d/config_test_7.conf", %[
39
+ k7 wildcard_include_2
40
+ ]
41
+ write_config "#{TMP_DIR}/config.d/config_test_8.conf", %[
42
+ <elem2 name>
43
+ @include ../dir/config_test_9.conf
44
+ </elem2>
45
+ ]
46
+ write_config "#{TMP_DIR}/dir/config_test_9.conf", %[
47
+ k9 embeded
48
+ <elem3 name>
49
+ nested nested_value
50
+ include hoge
51
+ </elem3>
52
+ ]
53
+ write_config "#{TMP_DIR}/config.d/00_config_test_8.conf", %[
54
+ k8 wildcard_include_3
55
+ <elem4 name>
56
+ include normal_parameter
57
+ </elem4>
58
+ ]
59
+ end
60
+
61
+ def prepare_config2
62
+ write_config "#{TMP_DIR}/config_test_1.rb", DSL_CONFIG_EXAMPLE
63
+ end
64
+
5
65
  DSL_CONFIG_EXAMPLE = %q[
6
66
  worker {
7
67
  hostname = "myhostname"
@@ -57,6 +117,14 @@ source {
57
117
  }
58
118
  ]
59
119
 
120
+ DSL_CONFIG_EXAMPLE_FOR_INCLUDE_CONF = %q[
121
+ include "#{TMP_DIR}/config_test_1.conf"
122
+ ]
123
+
124
+ DSL_CONFIG_EXAMPLE_FOR_INCLUDE_RB = %q[
125
+ include "#{TMP_DIR}/config_test_1.rb"
126
+ ]
127
+
60
128
  DSL_CONFIG_RETURNS_NON_ELEMENT = %q[
61
129
  worker {
62
130
  }
@@ -74,6 +142,9 @@ match('aa','bb'){
74
142
  DSL_CONFIG_WRONG_SYNTAX3 = %q[
75
143
  match('aa','bb')
76
144
  ]
145
+ DSL_CONFIG_WRONG_SYNTAX4 = %q[
146
+ include
147
+ ]
77
148
 
78
149
  module Fluent::Config
79
150
  class TestDSLParser < ::Test::Unit::TestCase
@@ -158,6 +229,112 @@ module Fluent::Config
158
229
  end
159
230
  end
160
231
 
232
+ sub_test_case 'with include conf' do
233
+ def setup
234
+ prepare_config1
235
+ @root = Fluent::Config::DSL::Parser.parse(DSL_CONFIG_EXAMPLE_FOR_INCLUDE_CONF, 'dsl_config_for_include.conf')
236
+ end
237
+ test 'include config' do
238
+ assert_equal('root_config', @root['k1'])
239
+ assert_equal('relative_path_include', @root['k2'])
240
+ assert_equal('relative_include_in_included_file', @root['k3'])
241
+ assert_equal('absolute_path_include', @root['k4'])
242
+ assert_equal('uri_include', @root['k5'])
243
+ assert_equal('wildcard_include_1', @root['k6'])
244
+ assert_equal('wildcard_include_2', @root['k7'])
245
+ assert_equal('wildcard_include_3', @root['k8'])
246
+ assert_equal([
247
+ 'k1',
248
+ 'k2',
249
+ 'k3',
250
+ 'k4',
251
+ 'k5',
252
+ 'k8', # Because of the file name this comes first.
253
+ 'k6',
254
+ 'k7',
255
+ ], @root.keys)
256
+
257
+ elem1 = @root.elements.find { |e| e.name == 'elem1' }
258
+ assert(elem1)
259
+ assert_equal('name', elem1.arg)
260
+ assert_equal('normal_parameter', elem1['include'])
261
+
262
+ elem2 = @root.elements.find { |e| e.name == 'elem2' }
263
+ assert(elem2)
264
+ assert_equal('name', elem2.arg)
265
+ assert_equal('embeded', elem2['k9'])
266
+ assert_not_include(elem2, 'include')
267
+
268
+ elem3 = elem2.elements.find { |e| e.name == 'elem3' }
269
+ assert(elem3)
270
+ assert_equal('nested_value', elem3['nested'])
271
+ assert_equal('hoge', elem3['include'])
272
+ end
273
+
274
+ # TODO: Add uri based include spec
275
+ end
276
+
277
+ sub_test_case 'with include rb' do
278
+ def setup
279
+ prepare_config2
280
+ @root = Fluent::Config::DSL::Parser.parse(DSL_CONFIG_EXAMPLE_FOR_INCLUDE_RB, 'dsl_config_for_include.rb')
281
+ end
282
+ sub_test_case '.parse' do
283
+ test 'makes root element' do
284
+ assert_equal('ROOT', @root.name)
285
+ assert_predicate(@root.arg, :empty?)
286
+ assert_equal(0, @root.keys.size)
287
+ end
288
+
289
+ test 'makes worker element for worker tag' do
290
+ assert_equal(1, @root.elements.size)
291
+
292
+ worker = @root.elements.first
293
+ assert_equal('worker', worker.name)
294
+ assert_predicate(worker.arg, :empty?)
295
+ assert_equal(0, worker.keys.size)
296
+ assert_equal(10, worker.elements.size)
297
+ end
298
+
299
+ test 'makes subsections for blocks, with variable substitution' do
300
+ ele4 = @root.elements.first.elements[4]
301
+
302
+ assert_equal('source', ele4.name)
303
+ assert_predicate(ele4.arg, :empty?)
304
+ assert_equal(2, ele4.keys.size)
305
+ assert_equal('tail', ele4['type'])
306
+ assert_equal("/var/log/httpd/access.part4.log", ele4['path'])
307
+ end
308
+
309
+ test 'makes user-defined sections with blocks' do
310
+ filter0 = @root.elements.first.elements[4].elements.first
311
+
312
+ assert_equal('filter', filter0.name)
313
+ assert_equal('bar.**', filter0.arg)
314
+ assert_equal('hoge', filter0['type'])
315
+ assert_equal('moge', filter0['val1'])
316
+ assert_equal(JSON.dump(['foo', 'bar', 'baz']), filter0['val2'])
317
+ assert_equal('10', filter0['val3'])
318
+ assert_equal('hoge', filter0['id'])
319
+
320
+ assert_equal(2, filter0.elements.size)
321
+ assert_equal('subsection', filter0.elements[0].name)
322
+ assert_equal('bar', filter0.elements[0]['foo'])
323
+ assert_equal('subsection', filter0.elements[1].name)
324
+ assert_equal('baz', filter0.elements[1]['foo'])
325
+ end
326
+
327
+ test 'makes values with user-assigned variable substitutions' do
328
+ match0 = @root.elements.first.elements[4].elements.last
329
+
330
+ assert_equal('match', match0.name)
331
+ assert_equal('{foo,bar}.**', match0.arg)
332
+ assert_equal('file', match0['type'])
333
+ assert_equal('/var/log/httpd/access.myhostname.4.log', match0['path'])
334
+ end
335
+ end
336
+ end
337
+
161
338
  sub_test_case 'with configuration that returns non element on top' do
162
339
  sub_test_case '.parse' do
163
340
  test 'does not crash' do
@@ -170,8 +347,9 @@ module Fluent::Config
170
347
  sub_test_case '.parse' do
171
348
  test 'raises ArgumentError correctly' do
172
349
  assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX1, 'dsl_config_wrong_syntax1') }
173
- assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX2, 'dsl_config_wrong_syntax1') }
174
- assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX3, 'dsl_config_wrong_syntax1') }
350
+ assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX2, 'dsl_config_wrong_syntax2') }
351
+ assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX3, 'dsl_config_wrong_syntax3') }
352
+ assert_raise(ArgumentError) { Fluent::Config::DSL::Parser.parse(DSL_CONFIG_WRONG_SYNTAX4, 'dsl_config_wrong_syntax4') }
175
353
  end
176
354
  end
177
355
  end