fluentd 1.8.1-x86-mingw32 → 1.9.0-x86-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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +14 -58
  3. data/.travis.yml +2 -17
  4. data/CHANGELOG.md +39 -0
  5. data/Gemfile +1 -4
  6. data/README.md +2 -6
  7. data/fluentd.gemspec +6 -6
  8. data/lib/fluent/command/cat.rb +1 -3
  9. data/lib/fluent/command/plugin_generator.rb +2 -1
  10. data/lib/fluent/config.rb +19 -0
  11. data/lib/fluent/config/literal_parser.rb +13 -8
  12. data/lib/fluent/config/v1_parser.rb +5 -3
  13. data/lib/fluent/engine.rb +60 -9
  14. data/lib/fluent/ext_monitor_require.rb +28 -0
  15. data/lib/fluent/load.rb +1 -1
  16. data/lib/fluent/msgpack_factory.rb +16 -4
  17. data/lib/fluent/plugin/base.rb +5 -0
  18. data/lib/fluent/plugin/buf_file.rb +10 -6
  19. data/lib/fluent/plugin/buf_file_single.rb +10 -6
  20. data/lib/fluent/plugin/buffer.rb +40 -22
  21. data/lib/fluent/plugin/buffer/chunk.rb +1 -1
  22. data/lib/fluent/plugin/in_http.rb +9 -9
  23. data/lib/fluent/plugin/in_tail.rb +8 -6
  24. data/lib/fluent/plugin/out_http.rb +2 -2
  25. data/lib/fluent/plugin/output.rb +2 -2
  26. data/lib/fluent/plugin/parser.rb +6 -0
  27. data/lib/fluent/plugin_helper/http_server.rb +0 -1
  28. data/lib/fluent/plugin_helper/record_accessor.rb +0 -8
  29. data/lib/fluent/plugin_helper/server.rb +6 -21
  30. data/lib/fluent/plugin_id.rb +9 -4
  31. data/lib/fluent/static_config_analysis.rb +194 -0
  32. data/lib/fluent/supervisor.rb +103 -28
  33. data/lib/fluent/system_config.rb +2 -1
  34. data/lib/fluent/test/driver/base.rb +4 -3
  35. data/lib/fluent/variable_store.rb +40 -0
  36. data/lib/fluent/version.rb +1 -1
  37. data/test/config/test_config_parser.rb +19 -16
  38. data/test/config/test_system_config.rb +6 -4
  39. data/test/plugin/test_in_exec.rb +9 -9
  40. data/test/plugin/test_in_forward.rb +10 -11
  41. data/test/plugin/test_in_http.rb +35 -3
  42. data/test/plugin/test_in_object_space.rb +3 -7
  43. data/test/plugin/test_out_exec_filter.rb +28 -45
  44. data/test/plugin/test_out_forward.rb +2 -2
  45. data/test/plugin/test_out_http.rb +8 -2
  46. data/test/plugin/test_output.rb +3 -3
  47. data/test/plugin/test_output_as_buffered.rb +1 -1
  48. data/test/plugin/test_output_as_buffered_overflow.rb +1 -1
  49. data/test/plugin/test_output_as_buffered_secondary.rb +2 -2
  50. data/test/plugin_helper/test_child_process.rb +45 -56
  51. data/test/plugin_helper/test_server.rb +13 -0
  52. data/test/plugin_helper/test_timer.rb +11 -13
  53. data/test/test_config.rb +27 -5
  54. data/test/test_engine.rb +203 -0
  55. data/test/test_output.rb +2 -2
  56. data/test/test_static_config_analysis.rb +177 -0
  57. data/test/test_supervisor.rb +18 -80
  58. data/test/test_test_drivers.rb +4 -3
  59. data/test/test_variable_store.rb +65 -0
  60. metadata +40 -27
  61. data/.gitlab/cicd-template.yaml +0 -10
  62. data/Vagrantfile +0 -17
@@ -751,6 +751,19 @@ class ServerPluginHelperTest < Test::Unit::TestCase
751
751
  assert_equal 1, errors.size
752
752
  assert_equal "BUG: this event is disabled for udp: close", errors.first.message
753
753
  end
754
+
755
+ test 'can bind IPv4 / IPv6 together' do
756
+ omit "IPv6 unavailable here" unless ipv6_enabled?
757
+
758
+ assert_nothing_raised do
759
+ @d.server_create_udp(:s_ipv4_udp, PORT, bind: '0.0.0.0', shared: false, max_bytes: 128) do |data, sock|
760
+ # ...
761
+ end
762
+ @d.server_create_udp(:s_ipv6_udp, PORT, bind: '::', shared: false, max_bytes: 128) do |data, sock|
763
+ # ...
764
+ end
765
+ end
766
+ end
754
767
  end
755
768
 
756
769
  module CertUtil
@@ -34,12 +34,12 @@ class TimerTest < Test::Unit::TestCase
34
34
  counter += 1
35
35
  end
36
36
 
37
- sleep 5
37
+ sleep 2
38
38
 
39
39
  d1.stop
40
40
  assert !d1.timer_running?
41
41
 
42
- assert{ counter >= 3 && counter <= 6 }
42
+ assert{ counter >= 1 && counter <= 2 }
43
43
 
44
44
  d1.shutdown; d1.close; d1.terminate
45
45
  end
@@ -52,19 +52,18 @@ class TimerTest < Test::Unit::TestCase
52
52
  counter1 = 0
53
53
  counter2 = 0
54
54
 
55
- d1.timer_execute(:t1, 1) do
55
+ d1.timer_execute(:t1, 0.2) do
56
56
  counter1 += 1
57
57
  end
58
- d1.timer_execute(:t2, 2) do
58
+ d1.timer_execute(:t2, 0.2) do
59
59
  counter2 += 1
60
60
  end
61
61
 
62
- sleep 6
63
-
62
+ sleep 1
64
63
  d1.stop
65
64
 
66
- assert{ counter1 >= 4 && counter1 <= 7 }
67
- assert{ counter2 >= 2 && counter2 <= 4 }
65
+ assert{ counter1 >= 4 && counter1 <= 5 }
66
+ assert{ counter2 >= 4 && counter2 <= 5 }
68
67
 
69
68
  d1.shutdown; d1.close; d1.terminate
70
69
  end
@@ -77,19 +76,18 @@ class TimerTest < Test::Unit::TestCase
77
76
  counter1 = 0
78
77
  counter2 = 0
79
78
 
80
- d1.timer_execute(:t1, 1) do
79
+ d1.timer_execute(:t1, 0.2) do
81
80
  counter1 += 1
82
81
  end
83
- d1.timer_execute(:t2, 1) do
82
+ d1.timer_execute(:t2, 0.2) do
84
83
  raise "abort!!!!!!" if counter2 > 1
85
84
  counter2 += 1
86
85
  end
87
86
 
88
- sleep 5
89
-
87
+ sleep 1
90
88
  d1.stop
91
89
 
92
- assert{ counter1 >= 3 && counter1 <= 6 }
90
+ assert{ counter1 >= 4 && counter1 <= 5 }
93
91
  assert{ counter2 == 2 }
94
92
  msg = "Unexpected error raised. Stopping the timer. title=:t2"
95
93
  assert{ d1.log.out.logs.any?{|line| line.include?("[error]:") && line.include?(msg) && line.include?("abort!!!!!!") } }
@@ -151,16 +151,16 @@ class ConfigTest < Test::Unit::TestCase
151
151
  assert_equal before_size, match_conf.unused.size
152
152
  end
153
153
 
154
- def write_config(path, data)
154
+ def write_config(path, data, encoding: 'utf-8')
155
155
  FileUtils.mkdir_p(File.dirname(path))
156
- File.open(path, "w") {|f| f.write data }
156
+ File.open(path, "w:#{encoding}:utf-8") {|f| f.write data }
157
157
  end
158
158
 
159
159
  def test_inline
160
160
  prepare_config
161
161
  opts = {
162
- :config_path => "#{TMP_DIR}/config_test_1.conf",
163
- :inline_config => "<source>\n type http\n port 2222\n </source>"
162
+ :config_path => "#{TMP_DIR}/config_test_1.conf",
163
+ :inline_config => "<source>\n type http\n port 2222\n </source>"
164
164
  }
165
165
  assert_nothing_raised do
166
166
  Fluent::Supervisor.new(opts)
@@ -175,5 +175,27 @@ class ConfigTest < Test::Unit::TestCase
175
175
  logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
176
176
  $log = Fluent::Log.new(logger)
177
177
  end
178
- end
179
178
 
179
+ sub_test_case '.build' do
180
+ test 'read config' do
181
+ write_config("#{TMP_DIR}/build/config_build.conf", 'key value')
182
+ c = Fluent::Config.build(config_path: "#{TMP_DIR}/build/config_build.conf")
183
+ assert_equal('value', c['key'])
184
+ end
185
+
186
+ test 'read config with encoding' do
187
+ write_config("#{TMP_DIR}/build/config_build2.conf", "#てすと\nkey value", encoding: 'shift_jis')
188
+
189
+ c = Fluent::Config.build(config_path: "#{TMP_DIR}/build/config_build2.conf", encoding: 'shift_jis')
190
+ assert_equal('value', c['key'])
191
+ end
192
+
193
+ test 'read config with additional_config' do
194
+ write_config("#{TMP_DIR}/build/config_build2.conf", "key value")
195
+
196
+ c = Fluent::Config.build(config_path: "#{TMP_DIR}/build/config_build2.conf", additional_config: 'key2 value2')
197
+ assert_equal('value', c['key'])
198
+ assert_equal('value2', c['key2'])
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,203 @@
1
+ require_relative 'helper'
2
+ require 'fluent/engine'
3
+ require 'fluent/config'
4
+ require 'fluent/input'
5
+ require 'fluent/system_config'
6
+
7
+ class EngineTest < ::Test::Unit::TestCase
8
+ class DummyEngineTestOutput < Fluent::Plugin::Output
9
+ Fluent::Plugin.register_output('dummy_engine_test', self)
10
+ def write(chunk); end
11
+ end
12
+
13
+ class DummyEngineTest2Output < Fluent::Plugin::Output
14
+ Fluent::Plugin.register_output('dummy_engine_test2', self)
15
+ def write(chunk); end
16
+ end
17
+
18
+ class DummyEngineTestInput < Fluent::Plugin::Input
19
+ Fluent::Plugin.register_input('dummy_engine_test', self)
20
+ def multi_workers_ready?; true; end
21
+ end
22
+
23
+ class DummyEngineTest2Input < Fluent::Plugin::Input
24
+ Fluent::Plugin.register_input('dummy_engine_test2', self)
25
+ def multi_workers_ready?; true; end
26
+ end
27
+
28
+ class DummyEngineClassVarTestInput < Fluent::Plugin::Input
29
+ Fluent::Plugin.register_input('dummy_engine_class_var_test', self)
30
+ @@test = nil
31
+ def multi_workers_ready?; true; end
32
+ end
33
+
34
+ sub_test_case '#reload_config' do
35
+ test 'reload new configuration' do
36
+ conf_data = <<-CONF
37
+ <source>
38
+ @type dummy_engine_test
39
+ </source>
40
+ <match>
41
+ @type dummy_engine_test
42
+ </match>
43
+ CONF
44
+
45
+ conf = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
46
+ system_config = Fluent::SystemConfig.create(conf)
47
+
48
+ engine = Fluent::EngineClass.new
49
+ engine.init(system_config)
50
+ engine.configure(conf)
51
+
52
+ assert_kind_of DummyEngineTestInput, engine.root_agent.inputs[0]
53
+ assert_kind_of DummyEngineTestOutput, engine.root_agent.outputs[0]
54
+
55
+ new_conf_data = <<-CONF
56
+ <source>
57
+ @type dummy_engine_test2
58
+ </source>
59
+ <match>
60
+ @type dummy_engine_test2
61
+ </match>
62
+ CONF
63
+
64
+ new_conf = Fluent::Config.parse(new_conf_data, '(test)', '(test_dir)', true)
65
+
66
+ agent = Fluent::RootAgent.new(log: $log, system_config: system_config)
67
+ stub(Fluent::RootAgent).new do
68
+ stub(agent).start.once
69
+ agent
70
+ end
71
+
72
+ engine.reload_config(new_conf)
73
+
74
+ assert_kind_of DummyEngineTest2Input, engine.root_agent.inputs[0]
75
+ assert_kind_of DummyEngineTest2Output, engine.root_agent.outputs[0]
76
+ end
77
+
78
+ test "doesn't start RootAgent when supervisor is true" do
79
+ conf_data = <<-CONF
80
+ <source>
81
+ @type dummy_engine_test
82
+ </source>
83
+ <match>
84
+ @type dummy_engine_test
85
+ </match>
86
+ CONF
87
+
88
+ conf = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
89
+ system_config = Fluent::SystemConfig.create(conf)
90
+
91
+ engine = Fluent::EngineClass.new
92
+ engine.init(system_config)
93
+ engine.configure(conf)
94
+
95
+ assert_kind_of DummyEngineTestInput, engine.root_agent.inputs[0]
96
+ assert_kind_of DummyEngineTestOutput, engine.root_agent.outputs[0]
97
+
98
+ new_conf_data = <<-CONF
99
+ <source>
100
+ @type dummy_engine_test2
101
+ </source>
102
+ <match>
103
+ @type dummy_engine_test2
104
+ </match>
105
+ CONF
106
+
107
+ new_conf = Fluent::Config.parse(new_conf_data, '(test)', '(test_dir)', true)
108
+
109
+ agent = Fluent::RootAgent.new(log: $log, system_config: system_config)
110
+ stub(Fluent::RootAgent).new do
111
+ stub(agent).start.never
112
+ agent
113
+ end
114
+
115
+ engine.reload_config(new_conf, supervisor: true)
116
+
117
+ assert_kind_of DummyEngineTest2Input, engine.root_agent.inputs[0]
118
+ assert_kind_of DummyEngineTest2Output, engine.root_agent.outputs[0]
119
+ end
120
+
121
+ test 'raise an error when conf is invalid' do
122
+ conf_data = <<-CONF
123
+ <source>
124
+ @type dummy_engine_test
125
+ </source>
126
+ <match>
127
+ @type dummy_engine_test
128
+ </match>
129
+ CONF
130
+
131
+ conf = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
132
+ system_config = Fluent::SystemConfig.create(conf)
133
+
134
+ engine = Fluent::EngineClass.new
135
+ engine.init(system_config)
136
+ engine.configure(conf)
137
+
138
+ assert_kind_of DummyEngineTestInput, engine.root_agent.inputs[0]
139
+ assert_kind_of DummyEngineTestOutput, engine.root_agent.outputs[0]
140
+
141
+ new_conf_data = <<-CONF
142
+ <source>
143
+ @type
144
+ </source>
145
+ CONF
146
+
147
+ new_conf = Fluent::Config.parse(new_conf_data, '(test)', '(test_dir)', true)
148
+
149
+ agent = Fluent::RootAgent.new(log: $log, system_config: system_config)
150
+ stub(Fluent::RootAgent).new do
151
+ stub(agent).start.never
152
+ agent
153
+ end
154
+
155
+ assert_raise(Fluent::ConfigError.new("Missing '@type' parameter on <source> directive")) do
156
+ engine.reload_config(new_conf)
157
+ end
158
+
159
+ assert_kind_of DummyEngineTestInput, engine.root_agent.inputs[0]
160
+ assert_kind_of DummyEngineTestOutput, engine.root_agent.outputs[0]
161
+ end
162
+
163
+ test 'raise an error when unreloadable exists' do
164
+ conf_data = <<-CONF
165
+ <source>
166
+ @type dummy_engine_test
167
+ </source>
168
+ <match>
169
+ @type dummy_engine_test
170
+ </match>
171
+ CONF
172
+
173
+ conf = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
174
+ system_config = Fluent::SystemConfig.create(conf)
175
+
176
+ engine = Fluent::EngineClass.new
177
+ engine.init(system_config)
178
+ engine.configure(conf)
179
+
180
+ assert_kind_of DummyEngineTestInput, engine.root_agent.inputs[0]
181
+ assert_kind_of DummyEngineTestOutput, engine.root_agent.outputs[0]
182
+
183
+ conf_data = <<-CONF
184
+ <source>
185
+ @type dummy_engine_class_var_test
186
+ </source>
187
+ <match>
188
+ @type dummy_engine_test
189
+ </match>
190
+ CONF
191
+
192
+ new_conf = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
193
+
194
+ e = assert_raise(Fluent::ConfigError) do
195
+ engine.reload_config(new_conf)
196
+ end
197
+ assert e.message.match?('Unreloadable plugin plugin: dummy_engine_class_var_test')
198
+
199
+ assert_kind_of DummyEngineTestInput, engine.root_agent.inputs[0]
200
+ assert_kind_of DummyEngineTestOutput, engine.root_agent.outputs[0]
201
+ end
202
+ end
203
+ end
@@ -116,7 +116,7 @@ module FluentOutputTest
116
116
  end
117
117
  end
118
118
 
119
- mock(d.instance.log).warn("secondary type should be same with primary one",
119
+ mock(d.instance.log).warn("Use different plugin for secondary. Check the plugin works with primary like secondary_file",
120
120
  { primary: d.instance.class.to_s, secondary: "Fluent::Plugin::Test2Output" })
121
121
  d.configure(CONFIG + %[
122
122
  <secondary>
@@ -132,7 +132,7 @@ module FluentOutputTest
132
132
  # ObjectBufferedOutput doesn't implement `custom_filter`
133
133
  d = Fluent::Test::BufferedOutputTestDriver.new(Fluent::ObjectBufferedOutput)
134
134
 
135
- mock(d.instance.log).warn("secondary type should be same with primary one",
135
+ mock(d.instance.log).warn("Use different plugin for secondary. Check the plugin works with primary like secondary_file",
136
136
  { primary: d.instance.class.to_s, secondary: "Fluent::Plugin::Test2Output" }).never
137
137
  d.configure(CONFIG + %[
138
138
  <secondary>
@@ -0,0 +1,177 @@
1
+ require_relative 'helper'
2
+
3
+ require 'fluent/config'
4
+ require 'fluent/static_config_analysis'
5
+ require 'fluent/plugin/out_forward'
6
+ require 'fluent/plugin/out_stdout'
7
+ require 'fluent/plugin/out_exec'
8
+ require 'fluent/plugin/in_forward'
9
+ require 'fluent/plugin/in_dummy'
10
+ require 'fluent/plugin/filter_grep'
11
+ require 'fluent/plugin/filter_stdout'
12
+ require 'fluent/plugin/filter_parser'
13
+
14
+ class StaticConfigAnalysisTest < ::Test::Unit::TestCase
15
+ sub_test_case '.call' do
16
+ test 'returns outputs, inputs and filters' do
17
+ conf_data = <<-CONF
18
+ <source>
19
+ @type forward
20
+ </source>
21
+ <filter>
22
+ @type grep
23
+ </filter>
24
+ <match>
25
+ @type forward
26
+ </match>
27
+ CONF
28
+
29
+ c = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
30
+ ret = Fluent::StaticConfigAnalysis.call(c)
31
+ assert_equal 1, ret.outputs.size
32
+ assert_kind_of Fluent::Plugin::ForwardOutput, ret.outputs[0].plugin
33
+ assert_equal 1, ret.inputs.size
34
+ assert_kind_of Fluent::Plugin::ForwardInput, ret.inputs[0].plugin
35
+ assert_equal 1, ret.filters.size
36
+ assert_kind_of Fluent::Plugin::GrepFilter, ret.filters[0].plugin
37
+ assert_empty ret.labels
38
+
39
+ assert_equal [Fluent::Plugin::ForwardOutput, Fluent::Plugin::ForwardInput, Fluent::Plugin::GrepFilter], ret.all_plugins.map(&:class)
40
+ end
41
+
42
+ test 'returns wrapped element with worker and label section' do
43
+ conf_data = <<-CONF
44
+ <source>
45
+ @type forward
46
+ </source>
47
+ <filter>
48
+ @type grep
49
+ </filter>
50
+ <match>
51
+ @type forward
52
+ </match>
53
+ <worker 0>
54
+ <source>
55
+ @type dummy
56
+ </source>
57
+ <filter>
58
+ @type parser
59
+ </filter>
60
+ <match>
61
+ @type exec
62
+ </match>
63
+ </worker>
64
+ <label @test>
65
+ <filter>
66
+ @type stdout
67
+ </filter>
68
+ <match>
69
+ @type stdout
70
+ </match>
71
+ </label>
72
+ CONF
73
+
74
+ c = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
75
+ ret = Fluent::StaticConfigAnalysis.call(c)
76
+ assert_equal [Fluent::Plugin::ExecOutput, Fluent::Plugin::StdoutOutput, Fluent::Plugin::ForwardOutput], ret.outputs.map(&:plugin).map(&:class)
77
+ assert_equal [Fluent::Plugin::DummyInput, Fluent::Plugin::ForwardInput], ret.inputs.map(&:plugin).map(&:class)
78
+ assert_equal [Fluent::Plugin::ParserFilter, Fluent::Plugin::StdoutFilter, Fluent::Plugin::GrepFilter], ret.filters.map(&:plugin).map(&:class)
79
+ assert_equal 1, ret.labels.size
80
+ assert_equal '@test', ret.labels[0].name
81
+ end
82
+
83
+ sub_test_case 'raises config error' do
84
+ data(
85
+ 'empty' => ['', 'Missing worker id on <worker> directive'],
86
+ 'invalid number' => ['a', 'worker id should be integer: a'],
87
+ 'worker id is negative' => ['-1', 'worker id should be integer: -1'],
88
+ 'min worker id is less than 0' => ['-1-1', 'worker id should be integer: -1-1'],
89
+ 'max worker id is less than 0' => ['1--1', 'worker id -1 specified by <worker> directive is not allowed. Available worker id is between 0 and 1'],
90
+ 'min worker id is greater than workers' => ['0-2', 'worker id 2 specified by <worker> directive is not allowed. Available worker id is between 0 and 1'],
91
+ 'max worker is less than min worker' => ['1-0', "greater first_worker_id<1> than last_worker_id<0> specified by <worker> directive is not allowed. Available multi worker assign syntax is <smaller_worker_id>-<greater_worker_id>"],
92
+ )
93
+ test 'when worker number is invalid' do |v|
94
+ val, msg = v
95
+ conf_data = <<-CONF
96
+ <worker #{val}>
97
+ </worker>
98
+ CONF
99
+
100
+ c = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
101
+ assert_raise(Fluent::ConfigError.new(msg)) do
102
+ Fluent::StaticConfigAnalysis.call(c, workers: 2)
103
+ end
104
+ end
105
+
106
+ test 'when worker number is duplicated' do
107
+ conf_data = <<-CONF
108
+ <worker 0-1>
109
+ </worker>
110
+ <worker 0-1>
111
+ </worker>
112
+ CONF
113
+
114
+ c = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
115
+ assert_raise(Fluent::ConfigError.new("specified worker_id<0> collisions is detected on <worker> directive. Available worker id(s): []")) do
116
+ Fluent::StaticConfigAnalysis.call(c, workers: 2)
117
+ end
118
+ end
119
+
120
+ test 'duplicated label exits' do
121
+ conf_data = <<-CONF
122
+ <label @dup>
123
+ </label>
124
+ <label @dup>
125
+ </label>
126
+ CONF
127
+
128
+ c = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
129
+ assert_raise(Fluent::ConfigError.new('Section <label @dup> appears twice')) do
130
+ Fluent::StaticConfigAnalysis.call(c, workers: 2)
131
+ end
132
+ end
133
+
134
+ test 'empty label' do
135
+ conf_data = <<-CONF
136
+ <label>
137
+ </label>
138
+ CONF
139
+
140
+ c = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
141
+ assert_raise(Fluent::ConfigError.new('Missing symbol argument on <label> directive')) do
142
+ Fluent::StaticConfigAnalysis.call(c, workers: 2)
143
+ end
144
+ end
145
+
146
+ data(
147
+ 'in filter' => 'filter',
148
+ 'in source' => 'source',
149
+ 'in match' => 'match',
150
+ )
151
+ test 'when @type is missing' do |name|
152
+ conf_data = <<-CONF
153
+ <#{name}>
154
+ @type
155
+ </#{name}>
156
+ CONF
157
+ c = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
158
+ assert_raise(Fluent::ConfigError.new("Missing '@type' parameter on <#{name}> directive")) do
159
+ Fluent::StaticConfigAnalysis.call(c)
160
+ end
161
+ end
162
+
163
+ test 'when worker has worker section' do
164
+ conf_data = <<-CONF
165
+ <worker 0>
166
+ <worker 0>
167
+ </worker>
168
+ </worker>
169
+ CONF
170
+ c = Fluent::Config.parse(conf_data, '(test)', '(test_dir)', true)
171
+ assert_raise(Fluent::ConfigError.new("<worker> section cannot have <worker> directive")) do
172
+ Fluent::StaticConfigAnalysis.call(c)
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end