fluentd 0.12.43 → 0.14.0
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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +6 -0
- data/.gitignore +2 -0
- data/.travis.yml +33 -21
- data/CONTRIBUTING.md +1 -0
- data/ChangeLog +1239 -0
- data/README.md +0 -25
- data/Rakefile +2 -1
- data/Vagrantfile +17 -0
- data/appveyor.yml +35 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_out_forward.conf +17 -0
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/out_forward_buf_file.conf +23 -0
- data/example/v0_12_filter.conf +8 -8
- data/fluent.conf +29 -0
- data/fluentd.gemspec +18 -11
- data/lib/fluent/agent.rb +60 -58
- data/lib/fluent/command/cat.rb +1 -1
- data/lib/fluent/command/debug.rb +7 -5
- data/lib/fluent/command/fluentd.rb +97 -2
- data/lib/fluent/compat/call_super_mixin.rb +67 -0
- data/lib/fluent/compat/filter.rb +50 -0
- data/lib/fluent/compat/formatter.rb +109 -0
- data/lib/fluent/compat/input.rb +50 -0
- data/lib/fluent/compat/output.rb +617 -0
- data/lib/fluent/compat/output_chain.rb +60 -0
- data/lib/fluent/compat/parser.rb +163 -0
- data/lib/fluent/compat/propagate_default.rb +62 -0
- data/lib/fluent/config.rb +23 -20
- data/lib/fluent/config/configure_proxy.rb +119 -70
- data/lib/fluent/config/dsl.rb +5 -18
- data/lib/fluent/config/element.rb +72 -8
- data/lib/fluent/config/error.rb +0 -3
- data/lib/fluent/config/literal_parser.rb +0 -2
- data/lib/fluent/config/parser.rb +4 -4
- data/lib/fluent/config/section.rb +39 -28
- data/lib/fluent/config/types.rb +2 -13
- data/lib/fluent/config/v1_parser.rb +1 -3
- data/lib/fluent/configurable.rb +48 -16
- data/lib/fluent/daemon.rb +15 -0
- data/lib/fluent/engine.rb +26 -52
- data/lib/fluent/env.rb +6 -4
- data/lib/fluent/event.rb +58 -11
- data/lib/fluent/event_router.rb +5 -5
- data/lib/fluent/filter.rb +2 -50
- data/lib/fluent/formatter.rb +4 -293
- data/lib/fluent/input.rb +2 -32
- data/lib/fluent/label.rb +2 -2
- data/lib/fluent/load.rb +3 -2
- data/lib/fluent/log.rb +107 -38
- data/lib/fluent/match.rb +0 -36
- data/lib/fluent/mixin.rb +117 -7
- data/lib/fluent/msgpack_factory.rb +62 -0
- data/lib/fluent/output.rb +7 -612
- data/lib/fluent/output_chain.rb +23 -0
- data/lib/fluent/parser.rb +4 -800
- data/lib/fluent/plugin.rb +100 -121
- data/lib/fluent/plugin/bare_output.rb +63 -0
- data/lib/fluent/plugin/base.rb +121 -0
- data/lib/fluent/plugin/buf_file.rb +101 -182
- data/lib/fluent/plugin/buf_memory.rb +9 -92
- data/lib/fluent/plugin/buffer.rb +473 -0
- data/lib/fluent/plugin/buffer/chunk.rb +135 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
- data/lib/fluent/plugin/exec_util.rb +80 -75
- data/lib/fluent/plugin/file_util.rb +33 -28
- data/lib/fluent/plugin/file_wrapper.rb +120 -0
- data/lib/fluent/plugin/filter.rb +51 -0
- data/lib/fluent/plugin/filter_grep.rb +13 -40
- data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
- data/lib/fluent/plugin/formatter.rb +93 -0
- data/lib/fluent/plugin/formatter_csv.rb +48 -0
- data/lib/fluent/plugin/formatter_hash.rb +32 -0
- data/lib/fluent/plugin/formatter_json.rb +47 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
- data/lib/fluent/plugin/formatter_out_file.rb +45 -0
- data/lib/fluent/plugin/formatter_single_value.rb +34 -0
- data/lib/fluent/plugin/formatter_stdout.rb +39 -0
- data/lib/fluent/plugin/in_debug_agent.rb +4 -0
- data/lib/fluent/plugin/in_dummy.rb +22 -18
- data/lib/fluent/plugin/in_exec.rb +18 -8
- data/lib/fluent/plugin/in_forward.rb +36 -79
- data/lib/fluent/plugin/in_gc_stat.rb +4 -0
- data/lib/fluent/plugin/in_http.rb +21 -18
- data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
- data/lib/fluent/plugin/in_object_space.rb +6 -1
- data/lib/fluent/plugin/in_stream.rb +7 -3
- data/lib/fluent/plugin/in_syslog.rb +46 -95
- data/lib/fluent/plugin/in_tail.rb +58 -640
- data/lib/fluent/plugin/in_tcp.rb +8 -1
- data/lib/fluent/plugin/in_udp.rb +8 -18
- data/lib/fluent/plugin/input.rb +33 -0
- data/lib/fluent/plugin/multi_output.rb +95 -0
- data/lib/fluent/plugin/out_buffered_null.rb +59 -0
- data/lib/fluent/plugin/out_copy.rb +11 -7
- data/lib/fluent/plugin/out_exec.rb +15 -11
- data/lib/fluent/plugin/out_exec_filter.rb +18 -10
- data/lib/fluent/plugin/out_file.rb +34 -5
- data/lib/fluent/plugin/out_forward.rb +25 -19
- data/lib/fluent/plugin/out_null.rb +0 -14
- data/lib/fluent/plugin/out_roundrobin.rb +11 -7
- data/lib/fluent/plugin/out_stdout.rb +5 -7
- data/lib/fluent/plugin/out_stream.rb +3 -1
- data/lib/fluent/plugin/output.rb +979 -0
- data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
- data/lib/fluent/plugin/parser.rb +244 -0
- data/lib/fluent/plugin/parser_apache.rb +24 -0
- data/lib/fluent/plugin/parser_apache2.rb +84 -0
- data/lib/fluent/plugin/parser_apache_error.rb +21 -0
- data/lib/fluent/plugin/parser_csv.rb +31 -0
- data/lib/fluent/plugin/parser_json.rb +79 -0
- data/lib/fluent/plugin/parser_ltsv.rb +50 -0
- data/lib/fluent/plugin/parser_multiline.rb +102 -0
- data/lib/fluent/plugin/parser_nginx.rb +24 -0
- data/lib/fluent/plugin/parser_none.rb +36 -0
- data/lib/fluent/plugin/parser_syslog.rb +82 -0
- data/lib/fluent/plugin/parser_tsv.rb +37 -0
- data/lib/fluent/plugin/socket_util.rb +119 -117
- data/lib/fluent/plugin/storage.rb +84 -0
- data/lib/fluent/plugin/storage_local.rb +116 -0
- data/lib/fluent/plugin/string_util.rb +16 -13
- data/lib/fluent/plugin_helper.rb +39 -0
- data/lib/fluent/plugin_helper/child_process.rb +298 -0
- data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
- data/lib/fluent/plugin_helper/event_loop.rb +118 -0
- data/lib/fluent/plugin_helper/retry_state.rb +177 -0
- data/lib/fluent/plugin_helper/storage.rb +308 -0
- data/lib/fluent/plugin_helper/thread.rb +147 -0
- data/lib/fluent/plugin_helper/timer.rb +85 -0
- data/lib/fluent/plugin_id.rb +63 -0
- data/lib/fluent/process.rb +21 -30
- data/lib/fluent/registry.rb +21 -9
- data/lib/fluent/root_agent.rb +115 -40
- data/lib/fluent/supervisor.rb +330 -320
- data/lib/fluent/system_config.rb +42 -18
- data/lib/fluent/test.rb +6 -1
- data/lib/fluent/test/base.rb +23 -3
- data/lib/fluent/test/driver/base.rb +247 -0
- data/lib/fluent/test/driver/event_feeder.rb +98 -0
- data/lib/fluent/test/driver/filter.rb +35 -0
- data/lib/fluent/test/driver/input.rb +31 -0
- data/lib/fluent/test/driver/output.rb +78 -0
- data/lib/fluent/test/driver/test_event_router.rb +45 -0
- data/lib/fluent/test/filter_test.rb +0 -1
- data/lib/fluent/test/formatter_test.rb +2 -1
- data/lib/fluent/test/input_test.rb +23 -17
- data/lib/fluent/test/output_test.rb +28 -39
- data/lib/fluent/test/parser_test.rb +1 -1
- data/lib/fluent/time.rb +104 -1
- data/lib/fluent/{status.rb → unique_id.rb} +15 -24
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +72 -0
- data/test/compat/test_calls_super.rb +164 -0
- data/test/config/test_config_parser.rb +83 -0
- data/test/config/test_configurable.rb +547 -274
- data/test/config/test_configure_proxy.rb +146 -29
- data/test/config/test_dsl.rb +3 -181
- data/test/config/test_element.rb +274 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_section.rb +79 -7
- data/test/config/test_system_config.rb +21 -0
- data/test/config/test_types.rb +3 -26
- data/test/helper.rb +78 -8
- data/test/plugin/test_bare_output.rb +118 -0
- data/test/plugin/test_base.rb +75 -0
- data/test/plugin/test_buf_file.rb +420 -521
- data/test/plugin/test_buf_memory.rb +32 -194
- data/test/plugin/test_buffer.rb +981 -0
- data/test/plugin/test_buffer_chunk.rb +110 -0
- data/test/plugin/test_buffer_file_chunk.rb +770 -0
- data/test/plugin/test_buffer_memory_chunk.rb +265 -0
- data/test/plugin/test_filter.rb +255 -0
- data/test/plugin/test_filter_grep.rb +2 -73
- data/test/plugin/test_filter_record_transformer.rb +24 -68
- data/test/plugin/test_filter_stdout.rb +6 -6
- data/test/plugin/test_in_debug_agent.rb +2 -0
- data/test/plugin/test_in_dummy.rb +11 -17
- data/test/plugin/test_in_exec.rb +6 -25
- data/test/plugin/test_in_forward.rb +112 -151
- data/test/plugin/test_in_gc_stat.rb +2 -0
- data/test/plugin/test_in_http.rb +106 -157
- data/test/plugin/test_in_object_space.rb +21 -5
- data/test/plugin/test_in_stream.rb +14 -13
- data/test/plugin/test_in_syslog.rb +30 -275
- data/test/plugin/test_in_tail.rb +95 -282
- data/test/plugin/test_in_tcp.rb +14 -0
- data/test/plugin/test_in_udp.rb +21 -67
- data/test/plugin/test_input.rb +122 -0
- data/test/plugin/test_multi_output.rb +180 -0
- data/test/plugin/test_out_buffered_null.rb +79 -0
- data/test/plugin/test_out_copy.rb +15 -2
- data/test/plugin/test_out_exec.rb +75 -25
- data/test/plugin/test_out_exec_filter.rb +74 -8
- data/test/plugin/test_out_file.rb +61 -7
- data/test/plugin/test_out_forward.rb +92 -15
- data/test/plugin/test_out_roundrobin.rb +1 -0
- data/test/plugin/test_out_stdout.rb +22 -13
- data/test/plugin/test_out_stream.rb +18 -0
- data/test/plugin/test_output.rb +515 -0
- data/test/plugin/test_output_as_buffered.rb +1540 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
- data/test/plugin/test_output_as_buffered_retries.rb +808 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
- data/test/plugin/test_output_as_standard.rb +362 -0
- data/test/plugin/test_owned_by.rb +35 -0
- data/test/plugin/test_storage.rb +167 -0
- data/test/plugin/test_storage_local.rb +8 -0
- data/test/plugin_helper/test_child_process.rb +599 -0
- data/test/plugin_helper/test_compat_parameters.rb +175 -0
- data/test/plugin_helper/test_event_emitter.rb +51 -0
- data/test/plugin_helper/test_event_loop.rb +52 -0
- data/test/plugin_helper/test_retry_state.rb +399 -0
- data/test/plugin_helper/test_storage.rb +411 -0
- data/test/plugin_helper/test_thread.rb +164 -0
- data/test/plugin_helper/test_timer.rb +100 -0
- data/test/scripts/exec_script.rb +0 -6
- data/test/scripts/fluent/plugin/out_test.rb +3 -0
- data/test/test_config.rb +13 -4
- data/test/test_event.rb +24 -13
- data/test/test_event_router.rb +8 -7
- data/test/test_event_time.rb +187 -0
- data/test/test_formatter.rb +13 -51
- data/test/test_input.rb +1 -1
- data/test/test_log.rb +239 -16
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +53 -66
- data/test/test_parser.rb +105 -323
- data/test/test_plugin_helper.rb +81 -0
- data/test/test_root_agent.rb +4 -52
- data/test/test_supervisor.rb +272 -0
- data/test/test_unique_id.rb +47 -0
- metadata +181 -55
- data/CHANGELOG.md +0 -710
- data/lib/fluent/buffer.rb +0 -365
- data/lib/fluent/plugin/filter_parser.rb +0 -107
- data/lib/fluent/plugin/in_status.rb +0 -76
- data/lib/fluent/test/helpers.rb +0 -86
- data/test/plugin/data/log/foo/bar2 +0 -0
- data/test/plugin/test_filter_parser.rb +0 -744
- data/test/plugin/test_in_status.rb +0 -38
- data/test/test_buffer.rb +0 -624
@@ -15,34 +15,25 @@
|
|
15
15
|
#
|
16
16
|
|
17
17
|
module Fluent
|
18
|
-
|
19
|
-
def
|
20
|
-
|
21
|
-
|
18
|
+
module UniqueId
|
19
|
+
def self.generate
|
20
|
+
now = Time.now.utc
|
21
|
+
u1 = ((now.to_i * 1000 * 1000 + now.usec) << 12 | rand(0xfff))
|
22
|
+
[u1 >> 32, u1 & 0xffffffff, rand(0xffffffff), rand(0xffffffff)].pack('NNNN')
|
22
23
|
end
|
23
24
|
|
24
|
-
def
|
25
|
-
|
26
|
-
(@entries[instance.object_id] ||= {})[name] = block
|
27
|
-
}
|
28
|
-
nil
|
25
|
+
def self.hex(unique_id)
|
26
|
+
unique_id.unpack('H*').first
|
29
27
|
end
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
}
|
40
|
-
}
|
29
|
+
module Mixin
|
30
|
+
def generate_unique_id
|
31
|
+
Fluent::UniqueId.generate
|
32
|
+
end
|
33
|
+
|
34
|
+
def dump_unique_id_hex(unique_id)
|
35
|
+
Fluent::UniqueId.hex(unique_id)
|
36
|
+
end
|
41
37
|
end
|
42
38
|
end
|
43
|
-
|
44
|
-
# Don't use this class from plugins.
|
45
|
-
# The interface may be changed
|
46
|
-
Status = StatusClass.new
|
47
39
|
end
|
48
|
-
|
data/lib/fluent/version.rb
CHANGED
@@ -0,0 +1,72 @@
|
|
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
|
+
INTEVENTOBJ_NAME = "fluentdwinsvc"
|
18
|
+
|
19
|
+
begin
|
20
|
+
|
21
|
+
require 'windows/debug'
|
22
|
+
require 'Windows/Library'
|
23
|
+
require 'win32/daemon'
|
24
|
+
require 'win32/event'
|
25
|
+
|
26
|
+
include Win32
|
27
|
+
include Windows::Library
|
28
|
+
include Windows::Debug
|
29
|
+
|
30
|
+
def read_fluentdopt
|
31
|
+
require 'win32/Registry'
|
32
|
+
Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM\\CurrentControlSet\\Services\\fluentdwinsvc") do |reg|
|
33
|
+
reg.read("fluentdopt")[1]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def service_main_start
|
38
|
+
ruby_path = 0.chr * 260
|
39
|
+
GetModuleFileName.call(0, ruby_path,260)
|
40
|
+
ruby_path = ruby_path.rstrip.gsub(/\\/, '/')
|
41
|
+
rubybin_dir = ruby_path[0, ruby_path.rindex("/")]
|
42
|
+
opt = read_fluentdopt
|
43
|
+
Process.spawn(rubybin_dir + "/ruby.exe " + rubybin_dir + "/fluentd " + opt + " -x " + INTEVENTOBJ_NAME)
|
44
|
+
end
|
45
|
+
|
46
|
+
class FluentdService < Daemon
|
47
|
+
@pid = 0
|
48
|
+
|
49
|
+
def service_main
|
50
|
+
opt = read_fluentdopt
|
51
|
+
@pid = service_main_start
|
52
|
+
while running?
|
53
|
+
sleep 10
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def service_stop
|
58
|
+
ev = Win32::Event.open(INTEVENTOBJ_NAME)
|
59
|
+
ev.set
|
60
|
+
ev.close
|
61
|
+
if @pid > 0
|
62
|
+
Porcess.waitpid(@pid)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
FluentdService.mainloop
|
68
|
+
|
69
|
+
rescue Exception => err
|
70
|
+
raise
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
# these are Fluent::Compat::* in fact
|
4
|
+
require 'fluent/input'
|
5
|
+
require 'fluent/output'
|
6
|
+
require 'fluent/filter'
|
7
|
+
|
8
|
+
class CompatCallsSuperTest < Test::Unit::TestCase
|
9
|
+
class DummyGoodInput < Fluent::Input
|
10
|
+
def configure(conf); super; end
|
11
|
+
def start; super; end
|
12
|
+
def before_shutdown; super; end
|
13
|
+
def shutdown; super; end
|
14
|
+
end
|
15
|
+
class DummyBadInput < Fluent::Input
|
16
|
+
def configure(conf); super; end
|
17
|
+
def start; end
|
18
|
+
def before_shutdown; end
|
19
|
+
def shutdown; end
|
20
|
+
end
|
21
|
+
class DummyGoodOutput < Fluent::Output
|
22
|
+
def configure(conf); super; end
|
23
|
+
def start; super; end
|
24
|
+
def before_shutdown; super; end
|
25
|
+
def shutdown; super; end
|
26
|
+
end
|
27
|
+
class DummyBadOutput < Fluent::Output
|
28
|
+
def configure(conf); super; end
|
29
|
+
def start; end
|
30
|
+
def before_shutdown; end
|
31
|
+
def shutdown; end
|
32
|
+
end
|
33
|
+
class DummyGoodFilter < Fluent::Filter
|
34
|
+
def configure(conf); super; end
|
35
|
+
def start; super; end
|
36
|
+
def before_shutdown; super; end
|
37
|
+
def shutdown; super; end
|
38
|
+
end
|
39
|
+
class DummyBadFilter < Fluent::Filter
|
40
|
+
def configure(conf); super; end
|
41
|
+
def start; end
|
42
|
+
def before_shutdown; end
|
43
|
+
def shutdown; end
|
44
|
+
end
|
45
|
+
|
46
|
+
setup do
|
47
|
+
Fluent::Test.setup
|
48
|
+
end
|
49
|
+
|
50
|
+
sub_test_case 'old API plugin which calls super properly' do
|
51
|
+
test 'Input#start, #before_shutdown and #shutdown calls all superclass methods properly' do
|
52
|
+
i = DummyGoodInput.new
|
53
|
+
i.configure(config_element())
|
54
|
+
assert i.configured?
|
55
|
+
|
56
|
+
i.start
|
57
|
+
assert i.started?
|
58
|
+
|
59
|
+
i.before_shutdown
|
60
|
+
assert i.before_shutdown?
|
61
|
+
|
62
|
+
i.shutdown
|
63
|
+
assert i.shutdown?
|
64
|
+
|
65
|
+
assert i.log.out.logs.empty?
|
66
|
+
end
|
67
|
+
|
68
|
+
test 'Output#start, #before_shutdown and #shutdown calls all superclass methods properly' do
|
69
|
+
i = DummyGoodOutput.new
|
70
|
+
i.configure(config_element())
|
71
|
+
assert i.configured?
|
72
|
+
|
73
|
+
i.start
|
74
|
+
assert i.started?
|
75
|
+
|
76
|
+
i.before_shutdown
|
77
|
+
assert i.before_shutdown?
|
78
|
+
|
79
|
+
i.shutdown
|
80
|
+
assert i.shutdown?
|
81
|
+
|
82
|
+
assert i.log.out.logs.empty?
|
83
|
+
end
|
84
|
+
|
85
|
+
test 'Filter#start, #before_shutdown and #shutdown calls all superclass methods properly' do
|
86
|
+
i = DummyGoodFilter.new
|
87
|
+
i.configure(config_element())
|
88
|
+
assert i.configured?
|
89
|
+
|
90
|
+
i.start
|
91
|
+
assert i.started?
|
92
|
+
|
93
|
+
i.before_shutdown
|
94
|
+
assert i.before_shutdown?
|
95
|
+
|
96
|
+
i.shutdown
|
97
|
+
assert i.shutdown?
|
98
|
+
|
99
|
+
assert i.log.out.logs.empty?
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
sub_test_case 'old API plugin which does not call super' do
|
104
|
+
test 'Input#start, #before_shutdown and #shutdown calls superclass methods forcedly with logs' do
|
105
|
+
i = DummyBadInput.new
|
106
|
+
i.configure(config_element())
|
107
|
+
assert i.configured?
|
108
|
+
|
109
|
+
i.start
|
110
|
+
assert i.started?
|
111
|
+
|
112
|
+
i.before_shutdown
|
113
|
+
assert i.before_shutdown?
|
114
|
+
|
115
|
+
i.shutdown
|
116
|
+
assert i.shutdown?
|
117
|
+
|
118
|
+
logs = i.log.out.logs
|
119
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #start: called it forcedly plugin=CompatCallsSuperTest::DummyBadInput") } }
|
120
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #before_shutdown: calling it forcedly plugin=CompatCallsSuperTest::DummyBadInput") } }
|
121
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #shutdown: calling it forcedly plugin=CompatCallsSuperTest::DummyBadInput") } }
|
122
|
+
end
|
123
|
+
|
124
|
+
test 'Output#start, #before_shutdown and #shutdown calls superclass methods forcedly with logs' do
|
125
|
+
i = DummyBadOutput.new
|
126
|
+
i.configure(config_element())
|
127
|
+
assert i.configured?
|
128
|
+
|
129
|
+
i.start
|
130
|
+
assert i.started?
|
131
|
+
|
132
|
+
i.before_shutdown
|
133
|
+
assert i.before_shutdown?
|
134
|
+
|
135
|
+
i.shutdown
|
136
|
+
assert i.shutdown?
|
137
|
+
|
138
|
+
logs = i.log.out.logs
|
139
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #start: called it forcedly plugin=CompatCallsSuperTest::DummyBadOutput") } }
|
140
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #before_shutdown: calling it forcedly plugin=CompatCallsSuperTest::DummyBadOutput") } }
|
141
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #shutdown: calling it forcedly plugin=CompatCallsSuperTest::DummyBadOutput") } }
|
142
|
+
end
|
143
|
+
|
144
|
+
test 'Filter#start, #before_shutdown and #shutdown calls superclass methods forcedly with logs' do
|
145
|
+
i = DummyBadFilter.new
|
146
|
+
i.configure(config_element())
|
147
|
+
assert i.configured?
|
148
|
+
|
149
|
+
i.start
|
150
|
+
assert i.started?
|
151
|
+
|
152
|
+
i.before_shutdown
|
153
|
+
assert i.before_shutdown?
|
154
|
+
|
155
|
+
i.shutdown
|
156
|
+
assert i.shutdown?
|
157
|
+
|
158
|
+
logs = i.log.out.logs
|
159
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #start: called it forcedly plugin=CompatCallsSuperTest::DummyBadFilter") } }
|
160
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #before_shutdown: calling it forcedly plugin=CompatCallsSuperTest::DummyBadFilter") } }
|
161
|
+
assert{ logs.any?{|l| l.include?("[warn]: super was not called in #shutdown: calling it forcedly plugin=CompatCallsSuperTest::DummyBadFilter") } }
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -23,6 +23,20 @@ module Fluent::Config
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
class AllTypes
|
27
|
+
include Fluent::Configurable
|
28
|
+
|
29
|
+
config_param :param_string, :string
|
30
|
+
config_param :param_enum, :enum, list: [:foo, :bar, :baz]
|
31
|
+
config_param :param_integer, :integer
|
32
|
+
config_param :param_float, :float
|
33
|
+
config_param :param_size, :size
|
34
|
+
config_param :param_bool, :bool
|
35
|
+
config_param :param_time, :time
|
36
|
+
config_param :param_hash, :hash
|
37
|
+
config_param :param_array, :array
|
38
|
+
end
|
39
|
+
|
26
40
|
class TestV1Parser < ::Test::Unit::TestCase
|
27
41
|
def read_config(path)
|
28
42
|
path = File.expand_path(path)
|
@@ -419,6 +433,75 @@ module Fluent::Config
|
|
419
433
|
conf2 = parse_text(conf.to_s) # use dumpped configuration to check unescape
|
420
434
|
assert_equal(expected, conf2.elements.first['k1'])
|
421
435
|
end
|
436
|
+
|
437
|
+
test 'all types' do
|
438
|
+
conf = parse_text(%[
|
439
|
+
param_string "value"
|
440
|
+
param_enum foo
|
441
|
+
param_integer 999
|
442
|
+
param_float 55.55
|
443
|
+
param_size 4k
|
444
|
+
param_bool true
|
445
|
+
param_time 10m
|
446
|
+
param_hash { "key1": "value1", "key2": 2 }
|
447
|
+
param_array ["value1", "value2", 100]
|
448
|
+
])
|
449
|
+
target = AllTypes.new.configure(conf)
|
450
|
+
assert_equal(conf.to_s, target.config.to_s)
|
451
|
+
expected = <<DUMP
|
452
|
+
<ROOT>
|
453
|
+
param_string "value"
|
454
|
+
param_enum foo
|
455
|
+
param_integer 999
|
456
|
+
param_float 55.55
|
457
|
+
param_size 4k
|
458
|
+
param_bool true
|
459
|
+
param_time 10m
|
460
|
+
param_hash {"key1":"value1","key2":2}
|
461
|
+
param_array ["value1","value2",100]
|
462
|
+
</ROOT>
|
463
|
+
DUMP
|
464
|
+
assert_equal(expected, conf.to_s)
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
class TestV0Parser < ::Test::Unit::TestCase
|
470
|
+
def parse_text(text)
|
471
|
+
basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
|
472
|
+
Fluent::Config::Parser.parse(StringIO.new(text), '(test)', basepath)
|
473
|
+
end
|
474
|
+
|
475
|
+
sub_test_case "Fluent::Config::Element#to_s" do
|
476
|
+
test 'all types' do
|
477
|
+
conf = parse_text(%[
|
478
|
+
param_string value
|
479
|
+
param_enum foo
|
480
|
+
param_integer 999
|
481
|
+
param_float 55.55
|
482
|
+
param_size 4k
|
483
|
+
param_bool true
|
484
|
+
param_time 10m
|
485
|
+
param_hash { "key1": "value1", "key2": 2 }
|
486
|
+
param_array ["value1", "value2", 100]
|
487
|
+
])
|
488
|
+
target = AllTypes.new.configure(conf)
|
489
|
+
assert_equal(conf.to_s, target.config.to_s)
|
490
|
+
expected = <<DUMP
|
491
|
+
<ROOT>
|
492
|
+
param_string value
|
493
|
+
param_enum foo
|
494
|
+
param_integer 999
|
495
|
+
param_float 55.55
|
496
|
+
param_size 4k
|
497
|
+
param_bool true
|
498
|
+
param_time 10m
|
499
|
+
param_hash { "key1": "value1", "key2": 2 }
|
500
|
+
param_array ["value1", "value2", 100]
|
501
|
+
</ROOT>
|
502
|
+
DUMP
|
503
|
+
assert_equal(expected, conf.to_s)
|
504
|
+
end
|
422
505
|
end
|
423
506
|
end
|
424
507
|
end
|
@@ -89,6 +89,16 @@ module ConfigurableSpec
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
+
class Init0
|
93
|
+
include Fluent::Configurable
|
94
|
+
config_section :sec1, init: true, multi: false do
|
95
|
+
config_param :name, :string, default: 'sec1'
|
96
|
+
end
|
97
|
+
config_section :sec2, init: true, multi: true do
|
98
|
+
config_param :name, :string, default: 'sec1'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
92
102
|
class Example0
|
93
103
|
include Fluent::Configurable
|
94
104
|
|
@@ -116,13 +126,6 @@ module ConfigurableSpec
|
|
116
126
|
end
|
117
127
|
end
|
118
128
|
|
119
|
-
class Example2 < Example1
|
120
|
-
config_section :detail, required: true, multi: false, alias: "information2" do
|
121
|
-
config_param :address, :string, default: "y"
|
122
|
-
config_param :phone_no, :string
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
129
|
class Example3
|
127
130
|
include Fluent::Configurable
|
128
131
|
|
@@ -138,15 +141,6 @@ module ConfigurableSpec
|
|
138
141
|
end
|
139
142
|
end
|
140
143
|
|
141
|
-
class Example4 < Example3
|
142
|
-
config_param :age, :integer, default: 20
|
143
|
-
|
144
|
-
config_section :appendix, required: false, multi: false, final: false do
|
145
|
-
config_param :name, :string, default: "y"
|
146
|
-
config_param :age, :integer, default: 10
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
144
|
class Example5
|
151
145
|
include Fluent::Configurable
|
152
146
|
|
@@ -159,11 +153,194 @@ module ConfigurableSpec
|
|
159
153
|
end
|
160
154
|
end
|
161
155
|
|
162
|
-
class
|
156
|
+
class Example6
|
163
157
|
include Fluent::Configurable
|
164
|
-
|
165
|
-
config_param :
|
166
|
-
|
158
|
+
config_param :obj1, :hash, default: {}
|
159
|
+
config_param :obj2, :array, default: []
|
160
|
+
end
|
161
|
+
|
162
|
+
module Overwrite
|
163
|
+
class Base
|
164
|
+
include Fluent::Configurable
|
165
|
+
|
166
|
+
config_param :name, :string, alias: :fullname
|
167
|
+
config_param :bool, :bool, alias: :flag
|
168
|
+
config_section :detail, required: false, multi: false, alias: "information" do
|
169
|
+
config_param :address, :string, default: "x"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
class Required < Base
|
174
|
+
config_section :detail, required: true do
|
175
|
+
config_param :address, :string, default: "x"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class Multi < Base
|
180
|
+
config_section :detail, multi: true do
|
181
|
+
config_param :address, :string, default: "x"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class Alias < Base
|
186
|
+
config_section :detail, alias: "information2" do
|
187
|
+
config_param :address, :string, default: "x"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
class DefaultOptions < Base
|
192
|
+
config_section :detail do
|
193
|
+
config_param :address, :string, default: "x"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
class DetailAddressDefault < Base
|
198
|
+
config_section :detail do
|
199
|
+
config_param :address, :string, default: "y"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
class AddParam < Base
|
204
|
+
config_section :detail do
|
205
|
+
config_param :phone_no, :string
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
class AddParamOverwriteAddress < Base
|
210
|
+
config_section :detail do
|
211
|
+
config_param :address, :string, default: "y"
|
212
|
+
config_param :phone_no, :string
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
module Final
|
218
|
+
# Show what is allowed in finalized sections
|
219
|
+
# InheritsFinalized < Finalized < Base
|
220
|
+
class Base
|
221
|
+
include Fluent::Configurable
|
222
|
+
config_section :appendix, multi: false, final: false do
|
223
|
+
config_param :code, :string
|
224
|
+
config_param :name, :string
|
225
|
+
config_param :address, :string, default: ""
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
class Finalized < Base
|
230
|
+
# to non-finalized section
|
231
|
+
# subclass can change type (code)
|
232
|
+
# add default value (name)
|
233
|
+
# change default value (address)
|
234
|
+
# add field (age)
|
235
|
+
config_section :appendix, final: true do
|
236
|
+
config_param :code, :integer
|
237
|
+
config_set_default :name, "y"
|
238
|
+
config_set_default :address, "-"
|
239
|
+
config_param :age, :integer, default: 10
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
class InheritsFinalized < Finalized
|
244
|
+
# to finalized section
|
245
|
+
# subclass can add default value (code)
|
246
|
+
# change default value (age)
|
247
|
+
# add field (phone_no)
|
248
|
+
config_section :appendix do
|
249
|
+
config_set_default :code, 2
|
250
|
+
config_set_default :age, 0
|
251
|
+
config_param :phone_no, :string
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# Show what is allowed/prohibited for finalized sections
|
256
|
+
class FinalizedBase
|
257
|
+
include Fluent::Configurable
|
258
|
+
config_section :appendix, param_name: :apd, init: false, required: true, multi: false, alias: "options", final: true do
|
259
|
+
config_param :name, :string
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
class FinalizedBase2
|
264
|
+
include Fluent::Configurable
|
265
|
+
config_section :appendix, param_name: :apd, init: false, required: false, multi: false, alias: "options", final: true do
|
266
|
+
config_param :name, :string
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# subclass can change init with adding default values
|
271
|
+
class OverwriteInit < FinalizedBase2
|
272
|
+
config_section :appendix, init: true do
|
273
|
+
config_set_default :name, "moris"
|
274
|
+
config_param :code, :integer, default: 0
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
# subclass cannot change type (name)
|
279
|
+
class Subclass < FinalizedBase
|
280
|
+
config_section :appendix do
|
281
|
+
config_param :name, :integer
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# subclass cannot change param_name
|
286
|
+
class OverwriteParamName < FinalizedBase
|
287
|
+
config_section :appendix, param_name: :adx do
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
# subclass cannot change final (section)
|
292
|
+
class OverwriteFinal < FinalizedBase
|
293
|
+
config_section :appendix, final: false do
|
294
|
+
config_param :name, :integer
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# subclass cannot change required
|
299
|
+
class OverwriteRequired < FinalizedBase
|
300
|
+
config_section :appendix, required: false do
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# subclass cannot change multi
|
305
|
+
class OverwriteMulti < FinalizedBase
|
306
|
+
config_section :appendix, multi: true do
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# subclass cannot change alias
|
311
|
+
class OverwriteAlias < FinalizedBase
|
312
|
+
config_section :appendix, alias: "options2" do
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
module OverwriteDefaults
|
318
|
+
class Owner
|
319
|
+
include Fluent::Configurable
|
320
|
+
config_set_default :key1, "V1"
|
321
|
+
config_section :buffer do
|
322
|
+
config_set_default :size_of_something, 1024
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
class SubOwner < Owner
|
327
|
+
config_section :buffer do
|
328
|
+
config_set_default :size_of_something, 2048
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
class FlatChild
|
333
|
+
include Fluent::Configurable
|
334
|
+
attr_accessor :owner
|
335
|
+
config_param :key1, :string, default: "v1"
|
336
|
+
end
|
337
|
+
|
338
|
+
class BufferChild
|
339
|
+
include Fluent::Configurable
|
340
|
+
attr_accessor :owner
|
341
|
+
configured_in :buffer
|
342
|
+
config_param :size_of_something, :size, default: 128
|
343
|
+
end
|
167
344
|
end
|
168
345
|
end
|
169
346
|
|
@@ -201,22 +378,18 @@ module Fluent::Config
|
|
201
378
|
end
|
202
379
|
|
203
380
|
sub_test_case '#configure' do
|
204
|
-
def e(attrs)
|
205
|
-
Fluent::Config::Element.new('', '', attrs, [])
|
206
|
-
end
|
207
|
-
|
208
381
|
test 'returns configurable object itself' do
|
209
382
|
b2 = ConfigurableSpec::Base2.new
|
210
|
-
assert_instance_of(ConfigurableSpec::Base2, b2.configure(
|
383
|
+
assert_instance_of(ConfigurableSpec::Base2, b2.configure(config_element("", "", {"name1" => "t1", "name5" => "t5", "opt3" => "a"})))
|
211
384
|
end
|
212
385
|
|
213
386
|
test 'raise errors without any specifications for param without defaults' do
|
214
387
|
b2 = ConfigurableSpec::Base2.new
|
215
|
-
assert_raise(Fluent::ConfigError) { b2.configure(
|
216
|
-
assert_raise(Fluent::ConfigError) { b2.configure(
|
217
|
-
assert_raise(Fluent::ConfigError) { b2.configure(
|
218
|
-
assert_raise(Fluent::ConfigError) { b2.configure(
|
219
|
-
assert_nothing_raised { b2.configure(
|
388
|
+
assert_raise(Fluent::ConfigError) { b2.configure(config_element("", "", {})) }
|
389
|
+
assert_raise(Fluent::ConfigError) { b2.configure(config_element("", "", {"name1" => "t1"})) }
|
390
|
+
assert_raise(Fluent::ConfigError) { b2.configure(config_element("", "", {"name5" => "t5"})) }
|
391
|
+
assert_raise(Fluent::ConfigError) { b2.configure(config_element("", "", {"name1" => "t1", "name5" => "t5"})) }
|
392
|
+
assert_nothing_raised { b2.configure(config_element("", "", {"name1" => "t1", "name5" => "t5", "opt3" => "a"})) }
|
220
393
|
|
221
394
|
assert_equal(["node", false, true, "t1", "base2", "base1", "base2", "t5", "base2"], b2.get_all)
|
222
395
|
assert_equal(:a, b2.opt3)
|
@@ -224,19 +397,19 @@ module Fluent::Config
|
|
224
397
|
|
225
398
|
test 'can configure bool values' do
|
226
399
|
b2a = ConfigurableSpec::Base2.new
|
227
|
-
assert_nothing_raised { b2a.configure(
|
400
|
+
assert_nothing_raised { b2a.configure(config_element("", "", {"flag1" => "true", "flag2" => "yes", "name1" => "t1", "name5" => "t5", "opt3" => "a"})) }
|
228
401
|
assert_true(b2a.flag1)
|
229
402
|
assert_true(b2a.flag2)
|
230
403
|
|
231
404
|
b2b = ConfigurableSpec::Base2.new
|
232
|
-
assert_nothing_raised { b2b.configure(
|
405
|
+
assert_nothing_raised { b2b.configure(config_element("", "", {"flag1" => false, "flag2" => "no", "name1" => "t1", "name5" => "t5", "opt3" => "a"})) }
|
233
406
|
assert_false(b2b.flag1)
|
234
407
|
assert_false(b2b.flag2)
|
235
408
|
end
|
236
409
|
|
237
410
|
test 'overwrites values of defaults' do
|
238
411
|
b2 = ConfigurableSpec::Base2.new
|
239
|
-
b2.configure(
|
412
|
+
b2.configure(config_element("", "", {"name1" => "t1", "name2" => "t2", "name3" => "t3", "name4" => "t4", "name5" => "t5", "opt1" => "foo", "opt3" => "b"}))
|
240
413
|
assert_equal("t1", b2.name1)
|
241
414
|
assert_equal("t2", b2.name2)
|
242
415
|
assert_equal("t3", b2.name3)
|
@@ -250,7 +423,7 @@ module Fluent::Config
|
|
250
423
|
end
|
251
424
|
|
252
425
|
test 'enum type rejects values which does not exist in list' do
|
253
|
-
default =
|
426
|
+
default = config_element("", "", {"name1" => "t1", "name2" => "t2", "name3" => "t3", "name4" => "t4", "name5" => "t5", "opt1" => "foo", "opt3" => "b"})
|
254
427
|
|
255
428
|
b2 = ConfigurableSpec::Base2.new
|
256
429
|
assert_nothing_raised { b2.configure(default) }
|
@@ -258,6 +431,37 @@ module Fluent::Config
|
|
258
431
|
assert_raise(Fluent::ConfigError) { b2.configure(default.merge({"opt2" => "fooooooo"})) }
|
259
432
|
assert_raise(Fluent::ConfigError) { b2.configure(default.merge({"opt3" => "c"})) }
|
260
433
|
end
|
434
|
+
|
435
|
+
sub_test_case 'default values should be duplicated before touched in plugin code' do
|
436
|
+
test 'default object should be dupped for cases configured twice' do
|
437
|
+
x6a = ConfigurableSpec::Example6.new
|
438
|
+
assert_nothing_raised { x6a.configure(config_element("")) }
|
439
|
+
assert_equal({}, x6a.obj1)
|
440
|
+
assert_equal([], x6a.obj2)
|
441
|
+
|
442
|
+
x6b = ConfigurableSpec::Example6.new
|
443
|
+
assert_nothing_raised { x6b.configure(config_element("")) }
|
444
|
+
assert_equal({}, x6b.obj1)
|
445
|
+
assert_equal([], x6b.obj2)
|
446
|
+
|
447
|
+
assert { x6a.obj1.object_id != x6b.obj1.object_id }
|
448
|
+
assert { x6a.obj2.object_id != x6b.obj2.object_id }
|
449
|
+
|
450
|
+
x6c = ConfigurableSpec::Example6.new
|
451
|
+
assert_nothing_raised { x6c.configure(config_element("")) }
|
452
|
+
assert_equal({}, x6c.obj1)
|
453
|
+
assert_equal([], x6c.obj2)
|
454
|
+
|
455
|
+
x6c.obj1['k'] = 'v'
|
456
|
+
x6c.obj2 << 'v'
|
457
|
+
|
458
|
+
assert_equal({'k' => 'v'}, x6c.obj1)
|
459
|
+
assert_equal(['v'], x6c.obj2)
|
460
|
+
|
461
|
+
assert_equal({}, x6a.obj1)
|
462
|
+
assert_equal([], x6a.obj2)
|
463
|
+
end
|
464
|
+
end
|
261
465
|
end
|
262
466
|
end
|
263
467
|
|
@@ -293,12 +497,6 @@ module Fluent::Config
|
|
293
497
|
end
|
294
498
|
|
295
499
|
sub_test_case '#configure' do
|
296
|
-
def e(name, arg = '', attrs = {}, elements = [])
|
297
|
-
attrs_str_keys = {}
|
298
|
-
attrs.each{|key, value| attrs_str_keys[key.to_s] = value }
|
299
|
-
config_element(name, arg, attrs_str_keys, elements)
|
300
|
-
end
|
301
|
-
|
302
500
|
BASE_ATTRS = {
|
303
501
|
"name1" => "1", "name2" => "2", "name3" => "3",
|
304
502
|
"name4" => "4", "name5" => "5", "name6" => "6",
|
@@ -306,68 +504,68 @@ module Fluent::Config
|
|
306
504
|
test 'checks required subsections' do
|
307
505
|
b3 = ConfigurableSpec::Base3.new
|
308
506
|
# branch sections required
|
309
|
-
assert_raise(Fluent::ConfigError) { b3.configure(
|
507
|
+
assert_raise(Fluent::ConfigError) { b3.configure(config_element('ROOT', '', BASE_ATTRS, [])) }
|
310
508
|
|
311
509
|
# branch argument required
|
312
510
|
msg = "'<branch ARG>' section requires argument, in section branch"
|
313
511
|
#expect{ b3.configure(e('ROOT', '', BASE_ATTRS, [e('branch', '')])) }.to raise_error(Fluent::ConfigError, msg)
|
314
|
-
assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(
|
512
|
+
assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(config_element('ROOT', '', BASE_ATTRS, [config_element('branch', '')])) }
|
315
513
|
|
316
514
|
# leaf is not required
|
317
|
-
assert_nothing_raised { b3.configure(
|
515
|
+
assert_nothing_raised { b3.configure(config_element('ROOT', '', BASE_ATTRS, [config_element('branch', 'branch_name')])) }
|
318
516
|
|
319
517
|
# leaf weight required
|
320
518
|
msg = "'weight' parameter is required, in section branch > leaf"
|
321
|
-
branch1 =
|
322
|
-
assert_nothing_raised { b3.configure(
|
323
|
-
branch2 =
|
324
|
-
assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(
|
325
|
-
branch3 =
|
326
|
-
assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(
|
519
|
+
branch1 = config_element('branch', 'branch_name', {size: 1}, [config_element('leaf', '10', {"weight" => 1})])
|
520
|
+
assert_nothing_raised { b3.configure(config_element('ROOT', '', BASE_ATTRS, [branch1])) }
|
521
|
+
branch2 = config_element('branch', 'branch_name', {size: 1}, [config_element('leaf', '20')])
|
522
|
+
assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(config_element('ROOT', '', BASE_ATTRS, [branch1, branch2])) }
|
523
|
+
branch3 = config_element('branch', 'branch_name', {size: 1}, [config_element('leaf', '10', {"weight" => 3}), config_element('leaf', '20')])
|
524
|
+
assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(config_element('ROOT', '', BASE_ATTRS, [branch3])) }
|
327
525
|
|
328
526
|
### worm not required
|
329
527
|
|
330
528
|
b4 = ConfigurableSpec::Base4.new
|
331
529
|
|
332
|
-
d1 =
|
333
|
-
d2 =
|
334
|
-
d3 =
|
335
|
-
assert_nothing_raised { b4.configure(
|
530
|
+
d1 = config_element('description1', '', {"text" => "d1"})
|
531
|
+
d2 = config_element('description2', '', {"text" => "d2"})
|
532
|
+
d3 = config_element('description3', '', {"text" => "d3"})
|
533
|
+
assert_nothing_raised { b4.configure(config_element('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup])) }
|
336
534
|
|
337
535
|
# description1 cannot be specified 2 or more
|
338
536
|
msg = "'<description1>' section cannot be written twice or more"
|
339
|
-
assert_raise(Fluent::ConfigError.new(msg)) { b4.configure(
|
537
|
+
assert_raise(Fluent::ConfigError.new(msg)) { b4.configure(config_element('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d1.dup, d3.dup])) }
|
340
538
|
|
341
539
|
# description2 cannot be specified 2 or more
|
342
540
|
msg = "'<description2>' section cannot be written twice or more"
|
343
|
-
assert_raise(Fluent::ConfigError.new(msg)) { b4.configure(
|
541
|
+
assert_raise(Fluent::ConfigError.new(msg)) { b4.configure(config_element('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup, d2.dup])) }
|
344
542
|
|
345
543
|
# description3 can be specified 2 or more
|
346
|
-
assert_nothing_raised { b4.configure(
|
544
|
+
assert_nothing_raised { b4.configure(config_element('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup, d3.dup])) }
|
347
545
|
end
|
348
546
|
|
349
547
|
test 'constructs confuguration object tree for Base3' do
|
350
|
-
conf =
|
548
|
+
conf = config_element(
|
351
549
|
'ROOT',
|
352
550
|
'',
|
353
551
|
BASE_ATTRS,
|
354
552
|
[
|
355
|
-
|
356
|
-
|
357
|
-
|
553
|
+
config_element('node', '', {"type" => "1"}), config_element('node', '', {"name" => "node2","type" => "2"}),
|
554
|
+
config_element('branch', 'b1.*', {}, []),
|
555
|
+
config_element('branch',
|
358
556
|
'b2.*',
|
359
|
-
{size
|
557
|
+
{"size" => 5},
|
360
558
|
[
|
361
|
-
|
362
|
-
|
363
|
-
|
559
|
+
config_element('leaf', 'THIS IS IGNORED', {"weight" => 55}, []),
|
560
|
+
config_element('leaf', 'THIS IS IGNORED', {"weight" => 50}, [ config_element('worm', '', {}) ]),
|
561
|
+
config_element('leaf', 'THIS IS IGNORED', {"weight" => 50}, [ config_element('worm', '', {"type" => "w1"}), config_element('worm', '', {"type" => "w2"}) ]),
|
364
562
|
]
|
365
563
|
),
|
366
|
-
|
564
|
+
config_element('branch',
|
367
565
|
'b3.*',
|
368
|
-
{size
|
566
|
+
{"size" => "503"},
|
369
567
|
[
|
370
|
-
|
568
|
+
config_element('leaf', 'THIS IS IGNORED', {"weight" => 55}, []),
|
371
569
|
]
|
372
570
|
)
|
373
571
|
],
|
@@ -424,18 +622,18 @@ module Fluent::Config
|
|
424
622
|
end
|
425
623
|
|
426
624
|
test 'constructs confuguration object tree for Base4' do
|
427
|
-
conf =
|
625
|
+
conf = config_element(
|
428
626
|
'ROOT',
|
429
627
|
'',
|
430
628
|
BASE_ATTRS,
|
431
629
|
[
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
630
|
+
config_element('node', '1', {"type" => "1"}), config_element('node', '2', {"name" => "node2"}),
|
631
|
+
config_element('description3', '', {"text" => "dddd3-1"}),
|
632
|
+
config_element('description2', 'd-2', {"text" => "dddd2"}),
|
633
|
+
config_element('description1', '', {"text" => "dddd1"}),
|
634
|
+
config_element('description3', 'd-3', {"text" => "dddd3-2"}),
|
635
|
+
config_element('description3', 'd-3a', {"text" => "dddd3-3"}),
|
636
|
+
config_element('node', '4', {"type" => "four"}),
|
439
637
|
],
|
440
638
|
)
|
441
639
|
b4 = ConfigurableSpec::Base4.new.configure(conf)
|
@@ -461,9 +659,9 @@ module Fluent::Config
|
|
461
659
|
assert_equal("node", b4.nodes[2].name)
|
462
660
|
assert_equal("four", b4.nodes[2].type)
|
463
661
|
|
464
|
-
#
|
465
|
-
#
|
466
|
-
#
|
662
|
+
# config_element('description3', '', {"text" => "dddd3-1"}),
|
663
|
+
# config_element('description3', 'd-3', {"text" => "dddd3-2"}),
|
664
|
+
# config_element('description3', 'd-3a', {"text" => "dddd3-3"}),
|
467
665
|
|
468
666
|
# NoMethodError: undefined method `class' for <Fluent::Config::Section {...}>:Fluent::Config::Section occurred. Should we add class method to Section?
|
469
667
|
#assert_equal('Fluent::Config::Section', b4.description1.class.name)
|
@@ -486,11 +684,11 @@ module Fluent::Config
|
|
486
684
|
end
|
487
685
|
|
488
686
|
test 'checks missing of specifications' do
|
489
|
-
conf0 =
|
687
|
+
conf0 = config_element('ROOT', '', {}, [])
|
490
688
|
ex01 = ConfigurableSpec::Example0.new
|
491
689
|
assert_raise(Fluent::ConfigError) { ex01.configure(conf0) }
|
492
690
|
|
493
|
-
complete =
|
691
|
+
complete = config_element('ROOT', '', {
|
494
692
|
"stringvalue" => "s1", "boolvalue" => "yes", "integervalue" => "10",
|
495
693
|
"sizevalue" => "10m", "timevalue" => "100s", "floatvalue" => "1.001",
|
496
694
|
"hashvalue" => '{"foo":1, "bar":2}',
|
@@ -500,18 +698,27 @@ module Fluent::Config
|
|
500
698
|
checker = lambda { |conf| ConfigurableSpec::Example0.new.configure(conf) }
|
501
699
|
|
502
700
|
assert_nothing_raised { checker.call(complete) }
|
503
|
-
assert_raise(Fluent::ConfigError) {
|
504
|
-
assert_raise(Fluent::ConfigError) {
|
505
|
-
assert_raise(Fluent::ConfigError) {
|
506
|
-
assert_raise(Fluent::ConfigError) {
|
507
|
-
assert_raise(Fluent::ConfigError) {
|
508
|
-
assert_raise(Fluent::ConfigError) {
|
509
|
-
assert_raise(Fluent::ConfigError) {
|
510
|
-
assert_raise(Fluent::ConfigError) {
|
701
|
+
assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("stringvalue"); checker.call(c) }
|
702
|
+
assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("boolvalue"); checker.call(c) }
|
703
|
+
assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("integervalue"); checker.call(c) }
|
704
|
+
assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("sizevalue"); checker.call(c) }
|
705
|
+
assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("timevalue"); checker.call(c) }
|
706
|
+
assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("floatvalue"); checker.call(c) }
|
707
|
+
assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("hashvalue"); checker.call(c) }
|
708
|
+
assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("arrayvalue"); checker.call(c) }
|
709
|
+
end
|
710
|
+
|
711
|
+
test 'generates section with default values for init:true sections' do
|
712
|
+
conf = config_element('ROOT', '', {}, [])
|
713
|
+
init0 = ConfigurableSpec::Init0.new
|
714
|
+
assert_nothing_raised { init0.configure(conf) }
|
715
|
+
assert init0.sec1
|
716
|
+
assert_equal "sec1", init0.sec1.name
|
717
|
+
assert_equal [], init0.sec2
|
511
718
|
end
|
512
719
|
|
513
720
|
test 'accepts configuration values as string representation' do
|
514
|
-
conf =
|
721
|
+
conf = config_element('ROOT', '', {
|
515
722
|
"stringvalue" => "s1", "boolvalue" => "yes", "integervalue" => "10",
|
516
723
|
"sizevalue" => "10m", "timevalue" => "10m", "floatvalue" => "1.001",
|
517
724
|
"hashvalue" => '{"foo":1, "bar":2}',
|
@@ -529,7 +736,7 @@ module Fluent::Config
|
|
529
736
|
end
|
530
737
|
|
531
738
|
test 'accepts configuration values as ruby value representation (especially for DSL)' do
|
532
|
-
conf =
|
739
|
+
conf = config_element('ROOT', '', {
|
533
740
|
"stringvalue" => "s1", "boolvalue" => true, "integervalue" => 10,
|
534
741
|
"sizevalue" => 10 * 1024 * 1024, "timevalue" => 10 * 60, "floatvalue" => 1.001,
|
535
742
|
"hashvalue" => {"foo" => 1, "bar" => 2},
|
@@ -547,7 +754,7 @@ module Fluent::Config
|
|
547
754
|
end
|
548
755
|
|
549
756
|
test 'gets both of true(yes) and false(no) for bool value parameter' do
|
550
|
-
conf =
|
757
|
+
conf = config_element('ROOT', '', {
|
551
758
|
"stringvalue" => "s1", "integervalue" => 10,
|
552
759
|
"sizevalue" => 10 * 1024 * 1024, "timevalue" => 10 * 60, "floatvalue" => 1.001,
|
553
760
|
"hashvalue" => {"foo" => 1, "bar" => 2},
|
@@ -574,93 +781,212 @@ module Fluent::Config
|
|
574
781
|
end
|
575
782
|
|
576
783
|
sub_test_case '.config_section' do
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
assert_equal
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
784
|
+
CONF1 = config_element('ROOT', '', {
|
785
|
+
'name' => 'tagomoris',
|
786
|
+
'bool' => true,
|
787
|
+
})
|
788
|
+
|
789
|
+
CONF2 = config_element('ROOT', '', {
|
790
|
+
'name' => 'tagomoris',
|
791
|
+
'bool' => true,
|
792
|
+
},
|
793
|
+
[config_element('detail', '', { 'phone_no' => "+81-00-0000-0000" }, [])])
|
794
|
+
|
795
|
+
CONF3 = config_element('ROOT', '', {
|
796
|
+
'name' => 'tagomoris',
|
797
|
+
'bool' => true,
|
798
|
+
},
|
799
|
+
[config_element('detail', '', { 'address' => "Chiyoda Tokyo Japan" }, [])])
|
800
|
+
|
801
|
+
CONF4 = config_element('ROOT', '', {
|
802
|
+
'name' => 'tagomoris',
|
803
|
+
'bool' => true,
|
804
|
+
},
|
805
|
+
[
|
806
|
+
config_element('detail', '', {
|
807
|
+
'address' => "Chiyoda Tokyo Japan",
|
808
|
+
'phone_no' => '+81-00-0000-0000'
|
809
|
+
},
|
810
|
+
[])
|
811
|
+
])
|
812
|
+
|
813
|
+
data(conf1: CONF1,
|
814
|
+
conf2: CONF2,
|
815
|
+
conf3: CONF3,
|
816
|
+
conf4: CONF4,)
|
817
|
+
test 'base class' do |data|
|
818
|
+
assert_nothing_raised { ConfigurableSpec::Overwrite::Base.new.configure(data) }
|
819
|
+
end
|
820
|
+
|
821
|
+
test 'subclass cannot overwrite required' do
|
822
|
+
assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: required")) do
|
823
|
+
ConfigurableSpec::Overwrite::Required.new.configure(CONF1)
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
827
|
+
test 'subclass cannot overwrite multi' do
|
828
|
+
assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: multi")) do
|
829
|
+
ConfigurableSpec::Overwrite::Multi.new.configure(CONF1)
|
830
|
+
end
|
831
|
+
end
|
832
|
+
|
833
|
+
test 'subclass cannot overwrite alias' do
|
834
|
+
assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: alias")) do
|
835
|
+
ConfigurableSpec::Overwrite::Alias.new.configure(CONF1)
|
836
|
+
end
|
837
|
+
end
|
838
|
+
|
839
|
+
test 'subclass uses superclass default options' do
|
840
|
+
base = ConfigurableSpec::Overwrite::Base.new.configure(CONF2)
|
841
|
+
sub = ConfigurableSpec::Overwrite::DefaultOptions.new.configure(CONF2)
|
842
|
+
detail_base = base.class.merged_configure_proxy.sections[:detail]
|
843
|
+
detail_sub = sub.class.merged_configure_proxy.sections[:detail]
|
844
|
+
detail_base_attributes = {
|
845
|
+
requried: detail_base.required,
|
846
|
+
multi: detail_base.multi,
|
847
|
+
alias: detail_base.alias,
|
848
|
+
}
|
849
|
+
detail_sub_attributes = {
|
850
|
+
requried: detail_sub.required,
|
851
|
+
multi: detail_sub.multi,
|
852
|
+
alias: detail_sub.alias,
|
853
|
+
}
|
854
|
+
assert_equal(detail_base_attributes, detail_sub_attributes)
|
855
|
+
end
|
856
|
+
|
857
|
+
test 'subclass can overwrite detail.address' do
|
858
|
+
base = ConfigurableSpec::Overwrite::Base.new.configure(CONF2)
|
859
|
+
target = ConfigurableSpec::Overwrite::DetailAddressDefault.new.configure(CONF2)
|
860
|
+
expected_addresses = ["x", "y"]
|
861
|
+
actual_addresses = [base.detail.address, target.detail.address]
|
862
|
+
assert_equal(expected_addresses, actual_addresses)
|
863
|
+
end
|
864
|
+
|
865
|
+
test 'subclass can add param' do
|
866
|
+
assert_raise(Fluent::ConfigError.new("'phone_no' parameter is required, in section detail")) do
|
867
|
+
ConfigurableSpec::Overwrite::AddParam.new.configure(CONF3)
|
868
|
+
end
|
869
|
+
target = ConfigurableSpec::Overwrite::AddParam.new.configure(CONF4)
|
870
|
+
expected = {
|
871
|
+
address: "Chiyoda Tokyo Japan",
|
872
|
+
phone_no: "+81-00-0000-0000"
|
873
|
+
}
|
874
|
+
actual = {
|
875
|
+
address: target.detail.address,
|
876
|
+
phone_no: target.detail.phone_no
|
877
|
+
}
|
878
|
+
assert_equal(expected, actual)
|
879
|
+
end
|
880
|
+
|
881
|
+
test 'subclass can add param with overwriting address' do
|
882
|
+
assert_raise(Fluent::ConfigError.new("'phone_no' parameter is required, in section detail")) do
|
883
|
+
ConfigurableSpec::Overwrite::AddParamOverwriteAddress.new.configure(CONF3)
|
884
|
+
end
|
885
|
+
target = ConfigurableSpec::Overwrite::AddParamOverwriteAddress.new.configure(CONF4)
|
886
|
+
expected = {
|
887
|
+
address: "Chiyoda Tokyo Japan",
|
888
|
+
phone_no: "+81-00-0000-0000"
|
889
|
+
}
|
890
|
+
actual = {
|
891
|
+
address: target.detail.address,
|
892
|
+
phone_no: target.detail.phone_no
|
893
|
+
}
|
894
|
+
assert_equal(expected, actual)
|
895
|
+
end
|
896
|
+
|
897
|
+
sub_test_case 'final' do
|
898
|
+
test 'base class has designed params and default values' do
|
899
|
+
b = ConfigurableSpec::Final::Base.new
|
900
|
+
appendix_conf = config_element('appendix', '', {"code" => "b", "name" => "base"})
|
901
|
+
b.configure(config_element('ROOT', '', {}, [appendix_conf]))
|
902
|
+
|
903
|
+
assert_equal "b", b.appendix.code
|
904
|
+
assert_equal "base", b.appendix.name
|
905
|
+
assert_equal "", b.appendix.address
|
906
|
+
end
|
907
|
+
|
908
|
+
test 'subclass can change type, add default value, change default value of parameters, and add parameters to non-finalized section' do
|
909
|
+
f = ConfigurableSpec::Final::Finalized.new
|
910
|
+
appendix_conf = config_element('appendix', '', {"code" => 1})
|
911
|
+
f.configure(config_element('ROOT', '', {}, [appendix_conf]))
|
912
|
+
|
913
|
+
assert_equal 1, f.appendix.code
|
914
|
+
assert_equal 'y', f.appendix.name
|
915
|
+
assert_equal "-", f.appendix.address
|
916
|
+
assert_equal 10, f.appendix.age
|
917
|
+
end
|
918
|
+
|
919
|
+
test 'subclass can add default value, change default value of parameters, and add parameters to finalized section' do
|
920
|
+
i = ConfigurableSpec::Final::InheritsFinalized.new
|
921
|
+
appendix_conf = config_element('appendix', '', {"phone_no" => "00-0000-0000"})
|
922
|
+
i.configure(config_element('ROOT', '', {}, [appendix_conf]))
|
923
|
+
|
924
|
+
assert_equal 2, i.appendix.code
|
925
|
+
assert_equal 0, i.appendix.age
|
926
|
+
assert_equal "00-0000-0000", i.appendix.phone_no
|
927
|
+
end
|
928
|
+
|
929
|
+
test 'finalized base class works as designed' do
|
930
|
+
b = ConfigurableSpec::Final::FinalizedBase.new
|
931
|
+
appendix_conf = config_element('options', '', {"name" => "moris"})
|
932
|
+
|
933
|
+
assert_nothing_raised do
|
934
|
+
b.configure(config_element('ROOT', '', {}, [appendix_conf]))
|
935
|
+
end
|
936
|
+
assert b.apd
|
937
|
+
assert_equal "moris", b.apd.name
|
938
|
+
end
|
939
|
+
|
940
|
+
test 'subclass can change init' do
|
941
|
+
n = ConfigurableSpec::Final::OverwriteInit.new
|
942
|
+
|
943
|
+
assert_nothing_raised do
|
944
|
+
n.configure(config_element('ROOT', ''))
|
945
|
+
end
|
946
|
+
assert n.apd
|
947
|
+
assert_equal "moris", n.apd.name
|
948
|
+
assert_equal 0, n.apd.code
|
949
|
+
end
|
950
|
+
|
951
|
+
test 'subclass cannot change parameter types in finalized sections' do
|
952
|
+
s = ConfigurableSpec::Final::Subclass.new
|
953
|
+
appendix_conf = config_element('options', '', {"name" => "1"})
|
954
|
+
|
955
|
+
assert_nothing_raised do
|
956
|
+
s.configure(config_element('ROOT', '', {}, [appendix_conf]))
|
957
|
+
end
|
958
|
+
assert_equal "1", s.apd.name
|
959
|
+
end
|
960
|
+
|
961
|
+
test 'subclass cannot change param_name of finalized section' do
|
962
|
+
assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: param_name")) do
|
963
|
+
ConfigurableSpec::Final::OverwriteParamName.new
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
967
|
+
test 'subclass cannot change final of finalized section' do
|
968
|
+
assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite finalized base class's config_section")) do
|
969
|
+
ConfigurableSpec::Final::OverwriteFinal.new
|
970
|
+
end
|
971
|
+
end
|
972
|
+
|
973
|
+
test 'subclass cannot change required of finalized section' do
|
974
|
+
assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: required")) do
|
975
|
+
ConfigurableSpec::Final::OverwriteRequired.new
|
976
|
+
end
|
977
|
+
end
|
978
|
+
|
979
|
+
test 'subclass cannot change multi of finalized section' do
|
980
|
+
assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: multi")) do
|
981
|
+
ConfigurableSpec::Final::OverwriteMulti.new
|
982
|
+
end
|
983
|
+
end
|
984
|
+
|
985
|
+
test 'subclass cannot change alias of finalized section' do
|
986
|
+
assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: alias")) do
|
987
|
+
ConfigurableSpec::Final::OverwriteAlias.new
|
988
|
+
end
|
989
|
+
end
|
664
990
|
end
|
665
991
|
end
|
666
992
|
end
|
@@ -679,15 +1005,14 @@ module Fluent::Config
|
|
679
1005
|
end
|
680
1006
|
|
681
1007
|
sub_test_case '#configure' do
|
682
|
-
def e(name, arg = '', attrs = {}, elements = [])
|
683
|
-
attrs_str_keys = {}
|
684
|
-
attrs.each{|key, value| attrs_str_keys[key.to_s] = value }
|
685
|
-
config_element(name, arg, attrs_str_keys, elements)
|
686
|
-
end
|
687
|
-
|
688
1008
|
test 'provides accessible data for alias attribute keys' do
|
689
1009
|
ex1 = ConfigurableSpec::Example1.new
|
690
|
-
|
1010
|
+
conf = config_element('ROOT', '', {
|
1011
|
+
"fullname" => "foo bar",
|
1012
|
+
"bool" => false
|
1013
|
+
},
|
1014
|
+
[config_element('information', '', {"address" => "Mountain View 0"})])
|
1015
|
+
ex1.configure(conf)
|
691
1016
|
assert_equal("foo bar", ex1.name)
|
692
1017
|
assert_not_nil(ex1.bool)
|
693
1018
|
assert_false(ex1.bool)
|
@@ -697,15 +1022,40 @@ module Fluent::Config
|
|
697
1022
|
end
|
698
1023
|
end
|
699
1024
|
|
700
|
-
sub_test_case '
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
1025
|
+
sub_test_case 'defaults can be overwritten by owner' do
|
1026
|
+
test 'for feature plugin which has flat parameters with parent' do
|
1027
|
+
owner = ConfigurableSpec::OverwriteDefaults::Owner.new
|
1028
|
+
child = ConfigurableSpec::OverwriteDefaults::FlatChild.new
|
1029
|
+
child.owner = owner
|
1030
|
+
child.configure(config_element('ROOT', '', {}, []))
|
1031
|
+
assert_equal "V1", child.key1
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
test 'for feature plugin which has parameters in subsection of parent' do
|
1035
|
+
owner = ConfigurableSpec::OverwriteDefaults::Owner.new
|
1036
|
+
child = ConfigurableSpec::OverwriteDefaults::BufferChild.new
|
1037
|
+
child.owner = owner
|
1038
|
+
child.configure(config_element('ROOT', '', {}, []))
|
1039
|
+
assert_equal 1024, child.size_of_something
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
test 'even in subclass of owner' do
|
1043
|
+
owner = ConfigurableSpec::OverwriteDefaults::SubOwner.new
|
1044
|
+
child = ConfigurableSpec::OverwriteDefaults::BufferChild.new
|
1045
|
+
child.owner = owner
|
1046
|
+
child.configure(config_element('ROOT', '', {}, []))
|
1047
|
+
assert_equal 2048, child.size_of_something
|
705
1048
|
end
|
1049
|
+
end
|
706
1050
|
|
1051
|
+
sub_test_case ':secret option' do
|
707
1052
|
setup do
|
708
|
-
@conf =
|
1053
|
+
@conf = config_element('ROOT', '',
|
1054
|
+
{
|
1055
|
+
'normal_param' => 'normal',
|
1056
|
+
'secret_param' => 'secret'
|
1057
|
+
},
|
1058
|
+
[config_element('section', '', {'normal_param2' => 'normal', 'secret_param2' => 'secret'} )])
|
709
1059
|
@example = ConfigurableSpec::Example5.new
|
710
1060
|
@example.configure(@conf)
|
711
1061
|
end
|
@@ -730,7 +1080,12 @@ module Fluent::Config
|
|
730
1080
|
end
|
731
1081
|
|
732
1082
|
test 'get plugin name when found unknown section' do
|
733
|
-
@conf =
|
1083
|
+
@conf = config_element('ROOT', '',
|
1084
|
+
{
|
1085
|
+
'normal_param' => 'normal',
|
1086
|
+
'secret_param' => 'secret'
|
1087
|
+
},
|
1088
|
+
[config_element('unknown', '', {'normal_param2' => 'normal', 'secret_param2' => 'secret'} )])
|
734
1089
|
@example = ConfigurableSpec::Example5.new
|
735
1090
|
@example.configure(@conf)
|
736
1091
|
@conf.elements.each { |e|
|
@@ -747,87 +1102,5 @@ module Fluent::Config
|
|
747
1102
|
end
|
748
1103
|
end
|
749
1104
|
end
|
750
|
-
sub_test_case 'non-required options for config_param' do
|
751
|
-
test 'desc must be a string if specified' do
|
752
|
-
assert_raise ArgumentError.new("key: desc must be a String, but Symbol") do
|
753
|
-
class InvalidDescClass
|
754
|
-
include Fluent::Configurable
|
755
|
-
config_param :key, :string, default: '', desc: :invalid_description
|
756
|
-
end
|
757
|
-
end
|
758
|
-
end
|
759
|
-
test 'alias must be a symbol if specified' do
|
760
|
-
assert_raise ArgumentError.new("key: alias must be a Symbol, but String") do
|
761
|
-
class InvalidAliasClass
|
762
|
-
include Fluent::Configurable
|
763
|
-
config_param :key, :string, default: '', alias: 'yay'
|
764
|
-
end
|
765
|
-
end
|
766
|
-
end
|
767
|
-
test 'deprecated must be a string if specified' do
|
768
|
-
assert_raise ArgumentError.new("key: deprecated must be a String, but TrueClass") do
|
769
|
-
class InvalidDeprecatedClass
|
770
|
-
include Fluent::Configurable
|
771
|
-
config_param :key, :string, default: '', deprecated: true
|
772
|
-
end
|
773
|
-
end
|
774
|
-
end
|
775
|
-
test 'obsoleted must be a string if specified' do
|
776
|
-
assert_raise ArgumentError.new("key: obsoleted must be a String, but TrueClass") do
|
777
|
-
class InvalidObsoletedClass
|
778
|
-
include Fluent::Configurable
|
779
|
-
config_param :key, :string, default: '', obsoleted: true
|
780
|
-
end
|
781
|
-
end
|
782
|
-
end
|
783
|
-
test 'value_type for hash must be a symbol' do
|
784
|
-
assert_raise ArgumentError.new("key: value_type must be a Symbol, but String") do
|
785
|
-
class InvalidValueTypeOfHashClass
|
786
|
-
include Fluent::Configurable
|
787
|
-
config_param :key, :hash, value_type: 'yay'
|
788
|
-
end
|
789
|
-
end
|
790
|
-
end
|
791
|
-
test 'value_type for array must be a symbol' do
|
792
|
-
assert_raise ArgumentError.new("key: value_type must be a Symbol, but String") do
|
793
|
-
class InvalidValueTypeOfArrayClass
|
794
|
-
include Fluent::Configurable
|
795
|
-
config_param :key, :array, value_type: 'yay'
|
796
|
-
end
|
797
|
-
end
|
798
|
-
end
|
799
|
-
end
|
800
|
-
sub_test_case 'enum parameters' do
|
801
|
-
test 'list must be specified as an array of symbols'
|
802
|
-
end
|
803
|
-
sub_test_case 'deprecated/obsoleted parameters' do
|
804
|
-
test 'both cannot be specified at once' do
|
805
|
-
assert_raise ArgumentError.new("param1: both of deprecated and obsoleted cannot be specified at once") do
|
806
|
-
class Buggy1
|
807
|
-
include Fluent::Configurable
|
808
|
-
config_param :param1, :string, default: '', deprecated: 'yay', obsoleted: 'foo!'
|
809
|
-
end
|
810
|
-
end
|
811
|
-
end
|
812
|
-
|
813
|
-
test 'warned if deprecated parameter is configured' do
|
814
|
-
obj = ConfigurableSpec::UnRecommended.new
|
815
|
-
obj.log = Fluent::Test::TestLogger.new
|
816
|
-
obj.configure(config_element('ROOT', '', {'key1' => 'yay'}, []))
|
817
|
-
|
818
|
-
assert_equal 'yay', obj.key1
|
819
|
-
first_log = obj.log.logs.first
|
820
|
-
assert{ first_log && first_log.include?("[warn]") && first_log.include?("'key1' parameter is deprecated: key1 will be removed.") }
|
821
|
-
end
|
822
|
-
|
823
|
-
test 'error raised if obsoleted parameter is configured' do
|
824
|
-
obj = ConfigurableSpec::UnRecommended.new
|
825
|
-
obj.log = Fluent::Test::TestLogger.new
|
826
|
-
|
827
|
-
assert_raise Fluent::ObsoletedParameterError.new("'key2' parameter is already removed: key2 has been removed.") do
|
828
|
-
obj.configure(config_element('ROOT', '', {'key2' => 'yay'}, []))
|
829
|
-
end
|
830
|
-
end
|
831
|
-
end
|
832
1105
|
end
|
833
1106
|
end
|