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.

Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.drone.yml +35 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +2 -0
  4. data/CHANGELOG.md +83 -0
  5. data/README.md +5 -1
  6. data/fluentd.gemspec +3 -2
  7. data/lib/fluent/clock.rb +4 -0
  8. data/lib/fluent/compat/output.rb +3 -3
  9. data/lib/fluent/compat/socket_util.rb +1 -1
  10. data/lib/fluent/config/element.rb +3 -3
  11. data/lib/fluent/config/literal_parser.rb +1 -1
  12. data/lib/fluent/config/section.rb +4 -1
  13. data/lib/fluent/error.rb +4 -0
  14. data/lib/fluent/event.rb +28 -24
  15. data/lib/fluent/event_router.rb +2 -1
  16. data/lib/fluent/log.rb +1 -1
  17. data/lib/fluent/msgpack_factory.rb +8 -0
  18. data/lib/fluent/plugin/bare_output.rb +4 -4
  19. data/lib/fluent/plugin/buf_file.rb +10 -1
  20. data/lib/fluent/plugin/buf_file_single.rb +219 -0
  21. data/lib/fluent/plugin/buffer.rb +62 -63
  22. data/lib/fluent/plugin/buffer/chunk.rb +21 -3
  23. data/lib/fluent/plugin/buffer/file_chunk.rb +44 -12
  24. data/lib/fluent/plugin/buffer/file_single_chunk.rb +314 -0
  25. data/lib/fluent/plugin/buffer/memory_chunk.rb +2 -1
  26. data/lib/fluent/plugin/compressable.rb +10 -6
  27. data/lib/fluent/plugin/filter_grep.rb +2 -2
  28. data/lib/fluent/plugin/formatter_csv.rb +10 -6
  29. data/lib/fluent/plugin/in_syslog.rb +10 -3
  30. data/lib/fluent/plugin/in_tail.rb +7 -2
  31. data/lib/fluent/plugin/in_tcp.rb +34 -7
  32. data/lib/fluent/plugin/multi_output.rb +4 -4
  33. data/lib/fluent/plugin/out_exec_filter.rb +1 -0
  34. data/lib/fluent/plugin/out_file.rb +13 -3
  35. data/lib/fluent/plugin/out_forward.rb +144 -588
  36. data/lib/fluent/plugin/out_forward/ack_handler.rb +161 -0
  37. data/lib/fluent/plugin/out_forward/connection_manager.rb +113 -0
  38. data/lib/fluent/plugin/out_forward/error.rb +28 -0
  39. data/lib/fluent/plugin/out_forward/failure_detector.rb +84 -0
  40. data/lib/fluent/plugin/out_forward/handshake_protocol.rb +121 -0
  41. data/lib/fluent/plugin/out_forward/load_balancer.rb +111 -0
  42. data/lib/fluent/plugin/out_forward/socket_cache.rb +138 -0
  43. data/lib/fluent/plugin/out_http.rb +231 -0
  44. data/lib/fluent/plugin/output.rb +29 -35
  45. data/lib/fluent/plugin/parser.rb +77 -0
  46. data/lib/fluent/plugin/parser_csv.rb +75 -0
  47. data/lib/fluent/plugin/parser_syslog.rb +106 -3
  48. data/lib/fluent/plugin_helper/server.rb +2 -2
  49. data/lib/fluent/plugin_helper/socket.rb +14 -1
  50. data/lib/fluent/plugin_helper/thread.rb +1 -0
  51. data/lib/fluent/root_agent.rb +1 -1
  52. data/lib/fluent/time.rb +4 -2
  53. data/lib/fluent/timezone.rb +21 -7
  54. data/lib/fluent/version.rb +1 -1
  55. data/test/command/test_fluentd.rb +1 -1
  56. data/test/command/test_plugin_generator.rb +18 -2
  57. data/test/config/test_configurable.rb +78 -40
  58. data/test/counter/test_store.rb +1 -1
  59. data/test/helper.rb +1 -0
  60. data/test/helpers/process_extenstion.rb +33 -0
  61. data/test/plugin/out_forward/test_ack_handler.rb +101 -0
  62. data/test/plugin/out_forward/test_connection_manager.rb +145 -0
  63. data/test/plugin/out_forward/test_handshake_protocol.rb +103 -0
  64. data/test/plugin/out_forward/test_load_balancer.rb +60 -0
  65. data/test/plugin/out_forward/test_socket_cache.rb +139 -0
  66. data/test/plugin/test_buf_file.rb +172 -2
  67. data/test/plugin/test_buf_file_single.rb +801 -0
  68. data/test/plugin/test_buffer.rb +4 -48
  69. data/test/plugin/test_buffer_file_chunk.rb +38 -1
  70. data/test/plugin/test_buffer_file_single_chunk.rb +621 -0
  71. data/test/plugin/test_buffer_memory_chunk.rb +1 -0
  72. data/test/plugin/test_formatter_csv.rb +16 -0
  73. data/test/plugin/test_in_syslog.rb +56 -6
  74. data/test/plugin/test_in_tail.rb +1 -1
  75. data/test/plugin/test_in_tcp.rb +25 -0
  76. data/test/plugin/test_out_forward.rb +150 -201
  77. data/test/plugin/test_out_http.rb +352 -0
  78. data/test/plugin/test_output_as_buffered.rb +27 -24
  79. data/test/plugin/test_parser.rb +40 -0
  80. data/test/plugin/test_parser_csv.rb +83 -0
  81. data/test/plugin/test_parser_syslog.rb +118 -19
  82. data/test/plugin_helper/test_record_accessor.rb +1 -1
  83. data/test/test_time_formatter.rb +140 -121
  84. 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 resolusion failed", "?"]
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, **kwargs, &block)
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
@@ -92,6 +92,7 @@ module Fluent
92
92
  end
93
93
  end
94
94
  thread.abort_on_exception = true
95
+ thread.name = title.to_s if thread.respond_to?(:name)
95
96
  @_threads_mutex.synchronize do
96
97
  @_threads[thread.object_id] = thread
97
98
  end
@@ -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 evetns with in_tail/`read_from_head true` case
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, @nsec / 1000.0)
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
- from_time(Time.now)
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)
@@ -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
- Time.at(time).localtime(offset).strftime(format)
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(Time.at(time).localtime(offset))
118
+ format.exec(time.to_time.localtime(offset))
108
119
  }
109
120
  else
110
121
  return Proc.new {|time|
111
- Time.at(time).localtime(offset).iso8601
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
- Time.at(time).localtime(tz.period_for_utc(time).utc_total_offset).strftime(format)
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
- format.exec(Time.at(time).localtime(tz.period_for_utc(time).utc_total_offset))
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
- Time.at(time).localtime(tz.period_for_utc(time).utc_total_offset).iso8601
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
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.6.3'
19
+ VERSION = '1.7.1'
20
20
 
21
21
  end
@@ -807,7 +807,7 @@ CONF
807
807
  )
808
808
  end
809
809
 
810
- test 'success to start workers when configured plugins as a chidren of MultiOutput only for specific worker do not support multi worker configuration' do
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
- FluentPluginGenerator.new([type, "fake"]).call
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
- FluentPluginGenerator.new(["--no-license", "filter", "fake"]).call
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 Example1
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 Example3
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 Example6
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 Example7
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::Example6.new
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::Example6.new
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::Example6.new
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::Example1.new
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::Example1.new
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::Example5.new
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::Example7.new
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
@@ -14,7 +14,7 @@ class CounterStoreTest < ::Test::Unit::TestCase
14
14
  @now = Fluent::EventTime.now
15
15
  end
16
16
 
17
- shutdown do
17
+ teardown do
18
18
  Timecop.return
19
19
  end
20
20