fluentd 1.6.3 → 1.7.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.
- checksums.yaml +4 -4
- data/.drone.yml +35 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +2 -0
- data/CHANGELOG.md +83 -0
- data/README.md +5 -1
- data/fluentd.gemspec +3 -2
- data/lib/fluent/clock.rb +4 -0
- data/lib/fluent/compat/output.rb +3 -3
- data/lib/fluent/compat/socket_util.rb +1 -1
- data/lib/fluent/config/element.rb +3 -3
- data/lib/fluent/config/literal_parser.rb +1 -1
- data/lib/fluent/config/section.rb +4 -1
- data/lib/fluent/error.rb +4 -0
- data/lib/fluent/event.rb +28 -24
- data/lib/fluent/event_router.rb +2 -1
- data/lib/fluent/log.rb +1 -1
- data/lib/fluent/msgpack_factory.rb +8 -0
- data/lib/fluent/plugin/bare_output.rb +4 -4
- data/lib/fluent/plugin/buf_file.rb +10 -1
- data/lib/fluent/plugin/buf_file_single.rb +219 -0
- data/lib/fluent/plugin/buffer.rb +62 -63
- data/lib/fluent/plugin/buffer/chunk.rb +21 -3
- data/lib/fluent/plugin/buffer/file_chunk.rb +44 -12
- data/lib/fluent/plugin/buffer/file_single_chunk.rb +314 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +2 -1
- data/lib/fluent/plugin/compressable.rb +10 -6
- data/lib/fluent/plugin/filter_grep.rb +2 -2
- data/lib/fluent/plugin/formatter_csv.rb +10 -6
- data/lib/fluent/plugin/in_syslog.rb +10 -3
- data/lib/fluent/plugin/in_tail.rb +7 -2
- data/lib/fluent/plugin/in_tcp.rb +34 -7
- data/lib/fluent/plugin/multi_output.rb +4 -4
- data/lib/fluent/plugin/out_exec_filter.rb +1 -0
- data/lib/fluent/plugin/out_file.rb +13 -3
- data/lib/fluent/plugin/out_forward.rb +144 -588
- data/lib/fluent/plugin/out_forward/ack_handler.rb +161 -0
- data/lib/fluent/plugin/out_forward/connection_manager.rb +113 -0
- data/lib/fluent/plugin/out_forward/error.rb +28 -0
- data/lib/fluent/plugin/out_forward/failure_detector.rb +84 -0
- data/lib/fluent/plugin/out_forward/handshake_protocol.rb +121 -0
- data/lib/fluent/plugin/out_forward/load_balancer.rb +111 -0
- data/lib/fluent/plugin/out_forward/socket_cache.rb +138 -0
- data/lib/fluent/plugin/out_http.rb +231 -0
- data/lib/fluent/plugin/output.rb +29 -35
- data/lib/fluent/plugin/parser.rb +77 -0
- data/lib/fluent/plugin/parser_csv.rb +75 -0
- data/lib/fluent/plugin/parser_syslog.rb +106 -3
- data/lib/fluent/plugin_helper/server.rb +2 -2
- data/lib/fluent/plugin_helper/socket.rb +14 -1
- data/lib/fluent/plugin_helper/thread.rb +1 -0
- data/lib/fluent/root_agent.rb +1 -1
- data/lib/fluent/time.rb +4 -2
- data/lib/fluent/timezone.rb +21 -7
- data/lib/fluent/version.rb +1 -1
- data/test/command/test_fluentd.rb +1 -1
- data/test/command/test_plugin_generator.rb +18 -2
- data/test/config/test_configurable.rb +78 -40
- data/test/counter/test_store.rb +1 -1
- data/test/helper.rb +1 -0
- data/test/helpers/process_extenstion.rb +33 -0
- data/test/plugin/out_forward/test_ack_handler.rb +101 -0
- data/test/plugin/out_forward/test_connection_manager.rb +145 -0
- data/test/plugin/out_forward/test_handshake_protocol.rb +103 -0
- data/test/plugin/out_forward/test_load_balancer.rb +60 -0
- data/test/plugin/out_forward/test_socket_cache.rb +139 -0
- data/test/plugin/test_buf_file.rb +172 -2
- data/test/plugin/test_buf_file_single.rb +801 -0
- data/test/plugin/test_buffer.rb +4 -48
- data/test/plugin/test_buffer_file_chunk.rb +38 -1
- data/test/plugin/test_buffer_file_single_chunk.rb +621 -0
- data/test/plugin/test_buffer_memory_chunk.rb +1 -0
- data/test/plugin/test_formatter_csv.rb +16 -0
- data/test/plugin/test_in_syslog.rb +56 -6
- data/test/plugin/test_in_tail.rb +1 -1
- data/test/plugin/test_in_tcp.rb +25 -0
- data/test/plugin/test_out_forward.rb +150 -201
- data/test/plugin/test_out_http.rb +352 -0
- data/test/plugin/test_output_as_buffered.rb +27 -24
- data/test/plugin/test_parser.rb +40 -0
- data/test/plugin/test_parser_csv.rb +83 -0
- data/test/plugin/test_parser_syslog.rb +118 -19
- data/test/plugin_helper/test_record_accessor.rb +1 -1
- data/test/test_time_formatter.rb +140 -121
- metadata +35 -6
@@ -377,7 +377,7 @@ module Fluent
|
|
377
377
|
end
|
378
378
|
|
379
379
|
# Use string "?" for port, not integer or nil. "?" is clear than -1 or nil in the log.
|
380
|
-
PEERADDR_FAILED = ["?", "?", "name
|
380
|
+
PEERADDR_FAILED = ["?", "?", "name resolution failed", "?"]
|
381
381
|
|
382
382
|
class CallbackSocket
|
383
383
|
def initialize(server_type, sock, enabled_events = [], close_socket: true)
|
@@ -722,7 +722,7 @@ module Fluent
|
|
722
722
|
|
723
723
|
return true
|
724
724
|
end
|
725
|
-
rescue Errno::EPIPE, Errno::ECONNRESET, OpenSSL::SSL::SSLError => e
|
725
|
+
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError => e
|
726
726
|
@log.trace "unexpected error before accepting TLS connection", error: e
|
727
727
|
close rescue nil
|
728
728
|
end
|
@@ -17,6 +17,9 @@
|
|
17
17
|
require 'socket'
|
18
18
|
require 'ipaddr'
|
19
19
|
require 'openssl'
|
20
|
+
if Fluent.windows?
|
21
|
+
require 'certstore'
|
22
|
+
end
|
20
23
|
|
21
24
|
require_relative 'socket_option'
|
22
25
|
|
@@ -96,7 +99,9 @@ module Fluent
|
|
96
99
|
host, port,
|
97
100
|
version: TLS_DEFAULT_VERSION, ciphers: CIPHERS_DEFAULT, insecure: false, verify_fqdn: true, fqdn: nil,
|
98
101
|
enable_system_cert_store: true, allow_self_signed_cert: false, cert_paths: nil,
|
99
|
-
cert_path: nil, private_key_path: nil, private_key_passphrase: nil,
|
102
|
+
cert_path: nil, private_key_path: nil, private_key_passphrase: nil,
|
103
|
+
cert_thumbprint: nil, cert_logical_store_name: nil, cert_use_enterprise_store: true,
|
104
|
+
**kwargs, &block)
|
100
105
|
|
101
106
|
host_is_ipaddress = IPAddr.new(host) rescue false
|
102
107
|
fqdn ||= host unless host_is_ipaddress
|
@@ -113,6 +118,14 @@ module Fluent
|
|
113
118
|
end
|
114
119
|
begin
|
115
120
|
if enable_system_cert_store
|
121
|
+
if Fluent.windows? && cert_logical_store_name
|
122
|
+
log.trace "loading Windows system certificate store"
|
123
|
+
loader = Certstore::OpenSSL::Loader.new(log, cert_store, cert_logical_store_name,
|
124
|
+
enterprise: cert_use_enterprise_store)
|
125
|
+
loader.load_cert_store
|
126
|
+
cert_store = loader.cert_store
|
127
|
+
context.cert = loader.get_certificate(cert_thumbprint) if cert_thumbprint
|
128
|
+
end
|
116
129
|
log.trace "loading system default certificate store"
|
117
130
|
cert_store.set_default_paths
|
118
131
|
end
|
data/lib/fluent/root_agent.rb
CHANGED
@@ -201,7 +201,7 @@ module Fluent
|
|
201
201
|
def start
|
202
202
|
lifecycle(desc: true) do |i| # instance
|
203
203
|
i.start unless i.started?
|
204
|
-
# Input#start sometimes emits lots of
|
204
|
+
# Input#start sometimes emits lots of events with in_tail/`read_from_head true` case
|
205
205
|
# and it causes deadlock for small buffer/queue output. To avoid such problem,
|
206
206
|
# buffer related output threads should be run before `Input#start`.
|
207
207
|
# This is why after_start should be called immediately after start call.
|
data/lib/fluent/time.rb
CHANGED
@@ -78,7 +78,7 @@ module Fluent
|
|
78
78
|
end
|
79
79
|
rescue
|
80
80
|
def to_time
|
81
|
-
Time.at(@sec
|
81
|
+
Time.at(Rational(@sec * 1_000_000_000 + @nsec, 1_000_000_000))
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -111,7 +111,9 @@ module Fluent
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def self.now
|
114
|
-
|
114
|
+
# This method is called many time. so call Process.clock_gettime directly instead of Fluent::Clock.real_now
|
115
|
+
now = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
|
116
|
+
Fluent::EventTime.new(now / 1_000_000_000, now % 1_000_000_000)
|
115
117
|
end
|
116
118
|
|
117
119
|
def self.parse(*args)
|
data/lib/fluent/timezone.rb
CHANGED
@@ -18,6 +18,15 @@ require 'tzinfo'
|
|
18
18
|
|
19
19
|
require 'fluent/config/error'
|
20
20
|
|
21
|
+
# For v0.12. Will be removed after v2
|
22
|
+
module IntegerExt
|
23
|
+
refine Integer do
|
24
|
+
def to_time
|
25
|
+
Time.at(self)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
21
30
|
module Fluent
|
22
31
|
class Timezone
|
23
32
|
# [+-]HH:MM, [+-]HHMM, [+-]HH
|
@@ -84,6 +93,8 @@ module Fluent
|
|
84
93
|
end
|
85
94
|
end
|
86
95
|
|
96
|
+
using IntegerExt
|
97
|
+
|
87
98
|
# Create a formatter for a timezone and optionally a format.
|
88
99
|
#
|
89
100
|
# An Proc object is returned. If the given timezone is invalid,
|
@@ -100,15 +111,15 @@ module Fluent
|
|
100
111
|
case
|
101
112
|
when format.is_a?(String)
|
102
113
|
return Proc.new {|time|
|
103
|
-
|
114
|
+
time.to_time.localtime(offset).strftime(format)
|
104
115
|
}
|
105
116
|
when format.is_a?(Strftime)
|
106
117
|
return Proc.new {|time|
|
107
|
-
format.exec(
|
118
|
+
format.exec(time.to_time.localtime(offset))
|
108
119
|
}
|
109
120
|
else
|
110
121
|
return Proc.new {|time|
|
111
|
-
|
122
|
+
time.to_time.localtime(offset).iso8601
|
112
123
|
}
|
113
124
|
end
|
114
125
|
end
|
@@ -124,15 +135,18 @@ module Fluent
|
|
124
135
|
case
|
125
136
|
when format.is_a?(String)
|
126
137
|
return Proc.new {|time|
|
127
|
-
|
138
|
+
time = time.to_time
|
139
|
+
time.localtime(tz.period_for_utc(time).utc_total_offset).strftime(format)
|
128
140
|
}
|
129
141
|
when format.is_a?(Strftime)
|
130
142
|
return Proc.new {|time|
|
131
|
-
|
143
|
+
time = time.to_time
|
144
|
+
format.exec(time.localtime(tz.period_for_utc(time).utc_total_offset))
|
132
145
|
}
|
133
146
|
else
|
134
147
|
return Proc.new {|time|
|
135
|
-
|
148
|
+
time = time.to_time
|
149
|
+
time.localtime(tz.period_for_utc(time).utc_total_offset).iso8601
|
136
150
|
}
|
137
151
|
end
|
138
152
|
end
|
@@ -149,7 +163,7 @@ module Fluent
|
|
149
163
|
when NAME_PATTERN
|
150
164
|
tz = TZInfo::Timezone.get(timezone)
|
151
165
|
->(time) {
|
152
|
-
tz.period_for_utc(time).utc_total_offset
|
166
|
+
tz.period_for_utc(time.to_time).utc_total_offset
|
153
167
|
}
|
154
168
|
end
|
155
169
|
end
|
data/lib/fluent/version.rb
CHANGED
@@ -807,7 +807,7 @@ CONF
|
|
807
807
|
)
|
808
808
|
end
|
809
809
|
|
810
|
-
test 'success to start workers when configured plugins as a
|
810
|
+
test 'success to start workers when configured plugins as a children of MultiOutput only for specific worker do not support multi worker configuration' do
|
811
811
|
script = <<-EOC
|
812
812
|
require 'fluent/plugin/output'
|
813
813
|
module Fluent::Plugin
|
@@ -16,6 +16,14 @@ class TestFluentPluginGenerator < Test::Unit::TestCase
|
|
16
16
|
FileUtils.rm_rf(TEMP_DIR)
|
17
17
|
end
|
18
18
|
|
19
|
+
def stub_git_process(target)
|
20
|
+
stub(target).spawn do |cmd, arg1, arg2|
|
21
|
+
assert_equal %w[git init .], [cmd, arg1, arg2]
|
22
|
+
-1
|
23
|
+
end
|
24
|
+
stub(Process).wait { |pid| assert_equal(pid, -1) }
|
25
|
+
end
|
26
|
+
|
19
27
|
sub_test_case "generate plugin" do
|
20
28
|
data(input: ["input", "in"],
|
21
29
|
output: ["output", "out"],
|
@@ -23,8 +31,10 @@ class TestFluentPluginGenerator < Test::Unit::TestCase
|
|
23
31
|
parser: ["parser", "parser"],
|
24
32
|
formatter: ["formatter", "formatter"])
|
25
33
|
test "generate plugin" do |(type, part)|
|
34
|
+
generator = FluentPluginGenerator.new([type, "fake"])
|
35
|
+
stub_git_process(generator)
|
26
36
|
capture_stdout do
|
27
|
-
|
37
|
+
generator.call
|
28
38
|
end
|
29
39
|
plugin_base_dir = Pathname("fluent-plugin-fake")
|
30
40
|
assert { plugin_base_dir.directory? }
|
@@ -49,8 +59,10 @@ class TestFluentPluginGenerator < Test::Unit::TestCase
|
|
49
59
|
end
|
50
60
|
|
51
61
|
test "no license" do
|
62
|
+
generator = FluentPluginGenerator.new(["--no-license", "filter", "fake"])
|
63
|
+
stub_git_process(generator)
|
52
64
|
capture_stdout do
|
53
|
-
|
65
|
+
generator.call
|
54
66
|
end
|
55
67
|
assert { !Pathname("fluent-plugin-fake/LICENSE").exist? }
|
56
68
|
assert { Pathname("fluent-plugin-fake/Gemfile").exist? }
|
@@ -72,6 +84,8 @@ class TestFluentPluginGenerator < Test::Unit::TestCase
|
|
72
84
|
"dash" => ["rewrite-tag-filter", "rewrite_tag_filter"])
|
73
85
|
test "plugin_name" do |(name, plugin_name)|
|
74
86
|
generator = FluentPluginGenerator.new(["filter", name])
|
87
|
+
stub_git_process(generator)
|
88
|
+
stub(Process).wait { |pid| assert_equal(pid, -1) }
|
75
89
|
capture_stdout do
|
76
90
|
generator.call
|
77
91
|
end
|
@@ -83,6 +97,8 @@ class TestFluentPluginGenerator < Test::Unit::TestCase
|
|
83
97
|
"dash" => ["rewrite-tag-filter", "fluent-plugin-rewrite-tag-filter"])
|
84
98
|
test "gem_name" do |(name, gem_name)|
|
85
99
|
generator = FluentPluginGenerator.new(["output", name])
|
100
|
+
stub_git_process(generator)
|
101
|
+
stub(Process).wait { |pid| assert_equal(pid, -1) }
|
86
102
|
capture_stdout do
|
87
103
|
generator.call
|
88
104
|
end
|
@@ -152,7 +152,7 @@ module ConfigurableSpec
|
|
152
152
|
config_param :arrayvalue, :array
|
153
153
|
end
|
154
154
|
|
155
|
-
class
|
155
|
+
class ExampleWithAlias
|
156
156
|
include Fluent::Configurable
|
157
157
|
|
158
158
|
config_param :name, :string, alias: :fullname
|
@@ -166,22 +166,7 @@ module ConfigurableSpec
|
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
169
|
-
class
|
170
|
-
include Fluent::Configurable
|
171
|
-
|
172
|
-
config_param :age, :integer, default: 10
|
173
|
-
|
174
|
-
config_section :appendix, required: true, multi: false, final: true do
|
175
|
-
config_param :type, :string
|
176
|
-
config_param :name, :string, default: "x"
|
177
|
-
end
|
178
|
-
|
179
|
-
def get_all
|
180
|
-
[@name, @detail]
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
class Example5
|
169
|
+
class ExampleWithSecret
|
185
170
|
include Fluent::Configurable
|
186
171
|
|
187
172
|
config_param :normal_param, :string
|
@@ -193,17 +178,42 @@ module ConfigurableSpec
|
|
193
178
|
end
|
194
179
|
end
|
195
180
|
|
196
|
-
class
|
181
|
+
class ExampleWithDefaultHashAndArray
|
197
182
|
include Fluent::Configurable
|
198
183
|
config_param :obj1, :hash, default: {}
|
199
184
|
config_param :obj2, :array, default: []
|
200
185
|
end
|
201
186
|
|
202
|
-
class
|
187
|
+
class ExampleWithSkipAccessor
|
203
188
|
include Fluent::Configurable
|
204
189
|
config_param :name, :string, default: 'example7', skip_accessor: true
|
205
190
|
end
|
206
191
|
|
192
|
+
class ExampleWithCustomSection
|
193
|
+
include Fluent::Configurable
|
194
|
+
config_param :name_param, :string
|
195
|
+
config_section :normal_section do
|
196
|
+
config_param :normal_section_param, :string
|
197
|
+
end
|
198
|
+
|
199
|
+
class CustomSection
|
200
|
+
include Fluent::Configurable
|
201
|
+
config_param :custom_section_param, :string
|
202
|
+
end
|
203
|
+
|
204
|
+
class AnotherElement
|
205
|
+
include Fluent::Configurable
|
206
|
+
end
|
207
|
+
|
208
|
+
def configure(conf)
|
209
|
+
super
|
210
|
+
conf.elements.each do |e|
|
211
|
+
next if e.name != 'custom_section'
|
212
|
+
CustomSection.new.configure(e)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
207
217
|
module Overwrite
|
208
218
|
class Base
|
209
219
|
include Fluent::Configurable
|
@@ -564,12 +574,12 @@ module Fluent::Config
|
|
564
574
|
|
565
575
|
sub_test_case 'default values should be duplicated before touched in plugin code' do
|
566
576
|
test 'default object should be dupped for cases configured twice' do
|
567
|
-
x6a = ConfigurableSpec::
|
577
|
+
x6a = ConfigurableSpec::ExampleWithDefaultHashAndArray.new
|
568
578
|
assert_nothing_raised { x6a.configure(config_element("")) }
|
569
579
|
assert_equal({}, x6a.obj1)
|
570
580
|
assert_equal([], x6a.obj2)
|
571
581
|
|
572
|
-
x6b = ConfigurableSpec::
|
582
|
+
x6b = ConfigurableSpec::ExampleWithDefaultHashAndArray.new
|
573
583
|
assert_nothing_raised { x6b.configure(config_element("")) }
|
574
584
|
assert_equal({}, x6b.obj1)
|
575
585
|
assert_equal([], x6b.obj2)
|
@@ -577,7 +587,7 @@ module Fluent::Config
|
|
577
587
|
assert { x6a.obj1.object_id != x6b.obj1.object_id }
|
578
588
|
assert { x6a.obj2.object_id != x6b.obj2.object_id }
|
579
589
|
|
580
|
-
x6c = ConfigurableSpec::
|
590
|
+
x6c = ConfigurableSpec::ExampleWithDefaultHashAndArray.new
|
581
591
|
assert_nothing_raised { x6c.configure(config_element("")) }
|
582
592
|
assert_equal({}, x6c.obj1)
|
583
593
|
assert_equal([], x6c.obj2)
|
@@ -1184,7 +1194,7 @@ module Fluent::Config
|
|
1184
1194
|
sub_test_case 'class defined with config_param/config_section having :alias' do
|
1185
1195
|
sub_test_case '#initialize' do
|
1186
1196
|
test 'does not create methods for alias' do
|
1187
|
-
ex1 = ConfigurableSpec::
|
1197
|
+
ex1 = ConfigurableSpec::ExampleWithAlias.new
|
1188
1198
|
assert_nothing_raised { ex1.name }
|
1189
1199
|
assert_raise(NoMethodError) { ex1.fullname }
|
1190
1200
|
assert_nothing_raised { ex1.bool }
|
@@ -1196,7 +1206,7 @@ module Fluent::Config
|
|
1196
1206
|
|
1197
1207
|
sub_test_case '#configure' do
|
1198
1208
|
test 'provides accessible data for alias attribute keys' do
|
1199
|
-
ex1 = ConfigurableSpec::
|
1209
|
+
ex1 = ConfigurableSpec::ExampleWithAlias.new
|
1200
1210
|
conf = config_element('ROOT', '', {
|
1201
1211
|
"fullname" => "foo bar",
|
1202
1212
|
"bool" => false
|
@@ -1288,7 +1298,7 @@ module Fluent::Config
|
|
1288
1298
|
'secret_param' => 'secret'
|
1289
1299
|
},
|
1290
1300
|
[config_element('section', '', {'normal_param2' => 'normal', 'secret_param2' => 'secret'} )])
|
1291
|
-
@example = ConfigurableSpec::
|
1301
|
+
@example = ConfigurableSpec::ExampleWithSecret.new
|
1292
1302
|
@example.configure(@conf)
|
1293
1303
|
end
|
1294
1304
|
|
@@ -1311,20 +1321,6 @@ module Fluent::Config
|
|
1311
1321
|
}
|
1312
1322
|
end
|
1313
1323
|
|
1314
|
-
test 'get plugin name when found unknown section' do
|
1315
|
-
@conf = config_element('ROOT', '',
|
1316
|
-
{
|
1317
|
-
'normal_param' => 'normal',
|
1318
|
-
'secret_param' => 'secret'
|
1319
|
-
},
|
1320
|
-
[config_element('unknown', '', {'normal_param2' => 'normal', 'secret_param2' => 'secret'} )])
|
1321
|
-
@example = ConfigurableSpec::Example5.new
|
1322
|
-
@example.configure(@conf)
|
1323
|
-
@conf.elements.each { |e|
|
1324
|
-
assert_equal(['ROOT', nil], e.unused_in)
|
1325
|
-
}
|
1326
|
-
end
|
1327
|
-
|
1328
1324
|
def assert_secret_param(key, value)
|
1329
1325
|
case key
|
1330
1326
|
when 'normal_param', 'normal_param2'
|
@@ -1335,9 +1331,51 @@ module Fluent::Config
|
|
1335
1331
|
end
|
1336
1332
|
end
|
1337
1333
|
|
1334
|
+
sub_test_case 'unused section' do
|
1335
|
+
test 'get plugin name when found unknown section' do
|
1336
|
+
conf = config_element('ROOT', '',
|
1337
|
+
{
|
1338
|
+
'name_param' => 'name',
|
1339
|
+
},
|
1340
|
+
[config_element('unknown', '', {'name_param' => 'normal'} )])
|
1341
|
+
example = ConfigurableSpec::ExampleWithCustomSection.new
|
1342
|
+
example.configure(conf)
|
1343
|
+
conf.elements.each { |e|
|
1344
|
+
assert_equal(['ROOT', nil], e.unused_in)
|
1345
|
+
}
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
test 'get an empty array when the section is defined without using config_section' do
|
1349
|
+
conf = config_element('ROOT', '',
|
1350
|
+
{
|
1351
|
+
'name_param' => 'name',
|
1352
|
+
},
|
1353
|
+
[config_element('custom_section', '', {'custom_section_param' => 'custom'} )])
|
1354
|
+
example = ConfigurableSpec::ExampleWithCustomSection.new
|
1355
|
+
example.configure(conf)
|
1356
|
+
conf.elements.each { |e|
|
1357
|
+
assert_equal([], e.unused_in)
|
1358
|
+
}
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
test 'get an empty array when the configuration is used in another element without any sections' do
|
1362
|
+
conf = config_element('ROOT', '',
|
1363
|
+
{
|
1364
|
+
'name_param' => 'name',
|
1365
|
+
},
|
1366
|
+
[config_element('normal_section', '', {'normal_section_param' => 'normal'} )])
|
1367
|
+
example = ConfigurableSpec::ExampleWithCustomSection.new
|
1368
|
+
example.configure(conf)
|
1369
|
+
ConfigurableSpec::ExampleWithCustomSection::AnotherElement.new.configure(conf)
|
1370
|
+
conf.elements.each { |e|
|
1371
|
+
assert_equal([], e.unused_in)
|
1372
|
+
}
|
1373
|
+
end
|
1374
|
+
end
|
1375
|
+
|
1338
1376
|
sub_test_case ':skip_accessor option' do
|
1339
1377
|
test 'it does not create accessor methods for parameters' do
|
1340
|
-
@example = ConfigurableSpec::
|
1378
|
+
@example = ConfigurableSpec::ExampleWithSkipAccessor.new
|
1341
1379
|
@example.configure(config_element('ROOT'))
|
1342
1380
|
assert_equal 'example7', @example.instance_variable_get(:@name)
|
1343
1381
|
assert_raise NoMethodError.new("undefined method `name' for #{@example}") do
|