fluentd 1.16.0 → 1.16.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/{bug_report.yaml → bug_report.yml} +1 -0
  3. data/.github/ISSUE_TEMPLATE/{feature_request.yaml → feature_request.yml} +1 -0
  4. data/.github/workflows/stale-actions.yml +24 -0
  5. data/.github/workflows/test.yml +39 -0
  6. data/CHANGELOG.md +161 -0
  7. data/CONTRIBUTING.md +1 -1
  8. data/MAINTAINERS.md +3 -3
  9. data/README.md +0 -2
  10. data/SECURITY.md +5 -9
  11. data/fluentd.gemspec +10 -2
  12. data/lib/fluent/command/ctl.rb +2 -2
  13. data/lib/fluent/command/fluentd.rb +1 -1
  14. data/lib/fluent/command/plugin_config_formatter.rb +1 -1
  15. data/lib/fluent/config/dsl.rb +1 -1
  16. data/lib/fluent/config/v1_parser.rb +2 -2
  17. data/lib/fluent/config/yaml_parser/parser.rb +4 -0
  18. data/lib/fluent/counter/server.rb +1 -1
  19. data/lib/fluent/counter/validator.rb +3 -3
  20. data/lib/fluent/engine.rb +1 -1
  21. data/lib/fluent/event.rb +8 -4
  22. data/lib/fluent/log.rb +9 -0
  23. data/lib/fluent/match.rb +1 -1
  24. data/lib/fluent/msgpack_factory.rb +6 -1
  25. data/lib/fluent/plugin/base.rb +1 -1
  26. data/lib/fluent/plugin/buffer.rb +96 -87
  27. data/lib/fluent/plugin/filter_record_transformer.rb +1 -1
  28. data/lib/fluent/plugin/in_forward.rb +1 -1
  29. data/lib/fluent/plugin/in_http.rb +8 -8
  30. data/lib/fluent/plugin/in_sample.rb +1 -1
  31. data/lib/fluent/plugin/in_tail/position_file.rb +32 -18
  32. data/lib/fluent/plugin/in_tail.rb +99 -31
  33. data/lib/fluent/plugin/in_tcp.rb +43 -0
  34. data/lib/fluent/plugin/out_exec_filter.rb +2 -2
  35. data/lib/fluent/plugin/out_file.rb +8 -0
  36. data/lib/fluent/plugin/output.rb +2 -2
  37. data/lib/fluent/plugin/parser_json.rb +4 -12
  38. data/lib/fluent/plugin_helper/event_loop.rb +2 -2
  39. data/lib/fluent/plugin_helper/record_accessor.rb +1 -1
  40. data/lib/fluent/plugin_helper/server.rb +8 -0
  41. data/lib/fluent/plugin_helper/thread.rb +3 -3
  42. data/lib/fluent/plugin_id.rb +1 -1
  43. data/lib/fluent/supervisor.rb +2 -2
  44. data/lib/fluent/system_config.rb +1 -1
  45. data/lib/fluent/version.rb +1 -1
  46. data/lib/fluent/winsvc.rb +28 -3
  47. data/templates/new_gem/test/helper.rb.erb +0 -1
  48. data/test/command/test_cat.rb +2 -2
  49. data/test/command/test_fluentd.rb +65 -12
  50. data/test/config/test_system_config.rb +2 -2
  51. data/test/helper.rb +27 -7
  52. data/test/plugin/in_tail/test_io_handler.rb +13 -14
  53. data/test/plugin/in_tail/test_position_file.rb +37 -8
  54. data/test/plugin/out_forward/test_ack_handler.rb +3 -3
  55. data/test/plugin/out_forward/test_socket_cache.rb +3 -3
  56. data/test/plugin/test_base.rb +1 -1
  57. data/test/plugin/test_buffer.rb +110 -0
  58. data/test/plugin/test_buffer_chunk.rb +11 -0
  59. data/test/plugin/test_in_forward.rb +11 -10
  60. data/test/plugin/test_in_http.rb +1 -1
  61. data/test/plugin/test_in_monitor_agent.rb +6 -6
  62. data/test/plugin/test_in_syslog.rb +25 -18
  63. data/test/plugin/test_in_tail.rb +639 -0
  64. data/test/plugin/test_in_tcp.rb +75 -5
  65. data/test/plugin/test_in_udp.rb +35 -1
  66. data/test/plugin/test_in_unix.rb +2 -2
  67. data/test/plugin/test_multi_output.rb +1 -1
  68. data/test/plugin/test_out_exec_filter.rb +14 -9
  69. data/test/plugin/test_out_file.rb +24 -4
  70. data/test/plugin/test_out_forward.rb +36 -42
  71. data/test/plugin/test_out_stream.rb +1 -1
  72. data/test/plugin/test_output.rb +12 -12
  73. data/test/plugin/test_output_as_buffered.rb +44 -44
  74. data/test/plugin/test_output_as_buffered_compress.rb +32 -18
  75. data/test/plugin/test_output_as_buffered_retries.rb +1 -1
  76. data/test/plugin/test_output_as_buffered_secondary.rb +2 -2
  77. data/test/plugin/test_parser_json.rb +31 -0
  78. data/test/plugin_helper/test_child_process.rb +15 -5
  79. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  80. data/test/plugin_helper/test_server.rb +110 -38
  81. data/test/plugin_helper/test_socket.rb +1 -1
  82. data/test/test_config.rb +6 -0
  83. data/test/test_event_router.rb +2 -2
  84. data/test/test_log.rb +38 -1
  85. data/test/test_msgpack_factory.rb +32 -0
  86. data/test/test_supervisor.rb +13 -0
  87. metadata +44 -17
  88. data/.github/workflows/linux-test.yaml +0 -36
  89. data/.github/workflows/macos-test.yaml +0 -34
  90. data/.github/workflows/windows-test.yaml +0 -49
@@ -5,7 +5,7 @@ require 'fluent/plugin/in_tcp'
5
5
  class TcpInputTest < Test::Unit::TestCase
6
6
  def setup
7
7
  Fluent::Test.setup
8
- @port = unused_port
8
+ @port = unused_port(protocol: :tcp)
9
9
  end
10
10
 
11
11
  def teardown
@@ -218,16 +218,14 @@ class TcpInputTest < Test::Unit::TestCase
218
218
  </client>
219
219
  </security>
220
220
  !)
221
- d.run(shutdown: false, expect_records: 1, timeout: 2) do
221
+ d.run(expect_records: 1, timeout: 2) do
222
222
  create_tcp_socket('127.0.0.1', @port) do |sock|
223
223
  sock.send("hello\n", 0)
224
224
  end
225
225
  end
226
226
 
227
- assert_equal 1, d.instance.log.logs.count { |l| l =~ /anonymous client/ }
227
+ assert_equal 1, d.logs.count { |l| l =~ /anonymous client/ }
228
228
  assert_equal 0, d.events.size
229
- ensure
230
- d.instance_shutdown if d&.instance
231
229
  end
232
230
  end
233
231
 
@@ -255,4 +253,76 @@ class TcpInputTest < Test::Unit::TestCase
255
253
  assert_equal 'hello', event[2]['msg']
256
254
  end
257
255
  end
256
+
257
+ sub_test_case "message_length_limit" do
258
+ data("batch_emit", { extract: "" }, keep: true)
259
+ data("single_emit", { extract: "<extract>\ntag_key tag\n</extract>\n" }, keep: true)
260
+ test "drop records exceeding limit" do |data|
261
+ message_length_limit = 10
262
+ d = create_driver(base_config + %!
263
+ message_length_limit #{message_length_limit}
264
+ <parse>
265
+ @type none
266
+ </parse>
267
+ #{data[:extract]}
268
+ !)
269
+ d.run(expect_records: 2, timeout: 10) do
270
+ create_tcp_socket('127.0.0.1', @port) do |sock|
271
+ sock.send("a" * message_length_limit + "\n", 0)
272
+ sock.send("b" * (message_length_limit + 1) + "\n", 0)
273
+ sock.send("c" * (message_length_limit - 1) + "\n", 0)
274
+ end
275
+ end
276
+
277
+ expected_records = [
278
+ "a" * message_length_limit,
279
+ "c" * (message_length_limit - 1)
280
+ ]
281
+ actual_records = d.events.collect do |event|
282
+ event[2]["message"]
283
+ end
284
+
285
+ assert_equal expected_records, actual_records
286
+ end
287
+
288
+ test "clear buffer and discard the subsequent data until the next delimiter" do |data|
289
+ message_length_limit = 12
290
+ d = create_driver(base_config + %!
291
+ message_length_limit #{message_length_limit}
292
+ delimiter ";"
293
+ <parse>
294
+ @type json
295
+ </parse>
296
+ #{data[:extract]}
297
+ !)
298
+ d.run(expect_records: 1, timeout: 10) do
299
+ create_tcp_socket('127.0.0.1', @port) do |sock|
300
+ sock.send('{"message":', 0)
301
+ sock.send('"hello', 0)
302
+ sleep 1 # To make the server read data and clear the buffer here.
303
+ sock.send('world!"};', 0) # This subsequent data must be discarded so that a parsing failure doesn't occur.
304
+ sock.send('{"k":"v"};', 0) # This will succeed to parse.
305
+ end
306
+ end
307
+
308
+ logs = d.logs.collect do |log|
309
+ log.gsub(/\A\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]\d{4} /, "")
310
+ end
311
+ actual_records = d.events.collect do |event|
312
+ event[2]
313
+ end
314
+
315
+ assert_equal(
316
+ {
317
+ # Asserting that '[warn]: pattern not matched message="world!\"}"' warning does not occur.
318
+ logs: ['[info]: The buffer size exceeds \'message_length_limit\', cleared: limit=12 size=17 head="{\"message\":\"hello"' + "\n"],
319
+ records: [{"k" => "v"}],
320
+ },
321
+ {
322
+ logs: logs[1..],
323
+ records: actual_records,
324
+ }
325
+ )
326
+ end
327
+ end
258
328
  end
@@ -5,7 +5,7 @@ require 'fluent/plugin/in_udp'
5
5
  class UdpInputTest < Test::Unit::TestCase
6
6
  def setup
7
7
  Fluent::Test.setup
8
- @port = unused_port
8
+ @port = unused_port(protocol: :udp)
9
9
  end
10
10
 
11
11
  def teardown
@@ -265,4 +265,38 @@ class UdpInputTest < Test::Unit::TestCase
265
265
  end
266
266
  end
267
267
  end
268
+
269
+ test 'message_length_limit' do
270
+ message_length_limit = 32
271
+
272
+ if Fluent.windows?
273
+ expected_records = ["0" * 30, "4" * 30]
274
+ else
275
+ expected_records = 1.upto(3).collect do |i|
276
+ "#{i}" * message_length_limit
277
+ end
278
+ expected_records.prepend("0" * 30)
279
+ expected_records.append("4" * 30)
280
+ end
281
+
282
+ d = create_driver(base_config + %!
283
+ format none
284
+ message_length_limit #{message_length_limit}
285
+ !)
286
+ d.run(expect_records: expected_records.size, timeout: 5) do
287
+ create_udp_socket('127.0.0.1', @port) do |u|
288
+ u.send("0" * 30 + "\n", 0)
289
+ 1.upto(3) do |i|
290
+ u.send("#{i}" * 40 + "\n", 0)
291
+ end
292
+ u.send("4" * 30 + "\n", 0)
293
+ end
294
+ end
295
+
296
+ actual_records = d.events.collect do |event|
297
+ event[2]["message"]
298
+ end
299
+
300
+ assert_equal expected_records, actual_records
301
+ end
268
302
  end
@@ -174,8 +174,8 @@ class UnixInputTest < Test::Unit::TestCase
174
174
  assert_equal 0, @d.events.size
175
175
 
176
176
  logs = @d.instance.log.logs
177
- assert_equal 1, logs.select { |line|
177
+ assert_equal 1, logs.count { |line|
178
178
  line =~ / \[warn\]: incoming data is broken: msg=#{data.inspect}/
179
- }.size, "should not accept broken chunk"
179
+ }, "should not accept broken chunk"
180
180
  end
181
181
  end unless Fluent.windows?
@@ -150,7 +150,7 @@ class MultiOutputTest < Test::Unit::TestCase
150
150
  log_size_for_metrics_plugin_helper = 4
151
151
  expected_warn_log_size = log_size_for_multi_output_itself + log_size_for_metrics_plugin_helper
152
152
  logs = @i.log.out.logs
153
- assert{ logs.select{|log| log.include?('[warn]') && log.include?("'type' is deprecated parameter name. use '@type' instead.") }.size == expected_warn_log_size }
153
+ assert{ logs.count{|log| log.include?('[warn]') && log.include?("'type' is deprecated parameter name. use '@type' instead.") } == expected_warn_log_size }
154
154
  end
155
155
 
156
156
  test '#emit_events calls #process always' do
@@ -500,10 +500,18 @@ class ExecFilterOutputTest < Test::Unit::TestCase
500
500
  d = create_driver(conf)
501
501
  time = event_time('2011-01-02 13:14:15')
502
502
 
503
- d.run(default_tag: 'test', expect_emits: 1, timeout: 10, start: true, shutdown: false){ d.feed(time, {"k1" => 0}) }
504
- d.run(default_tag: 'test', expect_emits: 1, timeout: 10, start: false, shutdown: false){ d.feed(time, {"k1" => 1}) }
505
- d.run(default_tag: 'test', expect_emits: 1, timeout: 10, start: false, shutdown: false){ d.feed(time, {"k1" => 2}) }
506
- d.run(default_tag: 'test', expect_emits: 1, timeout: 10, start: false, shutdown: false){ d.feed(time, {"k1" => 3}) }
503
+ d.run(default_tag: 'test', expect_emits: 4) do
504
+ d.feed(time, {"k1" => 0})
505
+ d.flush
506
+ sleep 0.5
507
+ d.feed(time, {"k1" => 1})
508
+ d.flush
509
+ sleep 0.5
510
+ d.feed(time, {"k1" => 2})
511
+ d.flush
512
+ sleep 0.5
513
+ d.feed(time, {"k1" => 3})
514
+ end
507
515
 
508
516
  assert_equal "2011-01-02 13:14:15\ttest\t0\n", d.formatted[0]
509
517
  assert_equal "2011-01-02 13:14:15\ttest\t1\n", d.formatted[1]
@@ -524,9 +532,6 @@ class ExecFilterOutputTest < Test::Unit::TestCase
524
532
  assert_equal pid_list[1], events[1][2]['child_pid']
525
533
  assert_equal pid_list[0], events[2][2]['child_pid']
526
534
  assert_equal pid_list[1], events[3][2]['child_pid']
527
-
528
- ensure
529
- d.run(start: false, shutdown: true)
530
535
  end
531
536
 
532
537
  # child process exits per 3 lines
@@ -597,8 +602,8 @@ class ExecFilterOutputTest < Test::Unit::TestCase
597
602
  # the number of pids should be same with number of child processes
598
603
  assert_equal 2, pid_list.size
599
604
  logs = d.instance.log.out.logs
600
- assert_equal 2, logs.select { |l| l.include?('child process exits with error code') }.size
601
- assert_equal 2, logs.select { |l| l.include?('respawning child process') }.size
605
+ assert_equal 2, logs.count { |l| l.include?('child process exits with error code') }
606
+ assert_equal 2, logs.count { |l| l.include?('respawning child process') }
602
607
 
603
608
  ensure
604
609
  d.run(start: false, shutdown: true)
@@ -130,7 +130,7 @@ class FileOutputTest < Test::Unit::TestCase
130
130
  'path' => "#{TMP_DIR}/${tag}/${type}/conf_test.%Y%m%d.%H%M.log",
131
131
  'add_path_suffix' => 'false',
132
132
  'append' => "true",
133
- 'symlink_path' => "#{TMP_DIR}/conf_test.current.log",
133
+ 'symlink_path' => "#{TMP_DIR}/${tag}/conf_test.current.log",
134
134
  'compress' => 'gzip',
135
135
  'recompress' => 'true',
136
136
  }, [
@@ -183,6 +183,26 @@ class FileOutputTest < Test::Unit::TestCase
183
183
  Fluent::Test::Driver::Output.new(Fluent::Plugin::NullOutput).configure(conf)
184
184
  end
185
185
  end
186
+
187
+ test 'warning for symlink_path not including correct placeholders corresponding to chunk keys' do
188
+ omit "Windows doesn't support symlink" if Fluent.windows?
189
+ conf = config_element('match', '**', {
190
+ 'path' => "#{TMP_DIR}/${tag}/${key1}/${key2}/conf_test.%Y%m%d.%H%M.log",
191
+ 'symlink_path' => "#{TMP_DIR}/conf_test.current.log",
192
+ }, [
193
+ config_element('buffer', 'time,tag,key1,key2', {
194
+ '@type' => 'file',
195
+ 'timekey' => '1d',
196
+ 'path' => "#{TMP_DIR}/buf_conf_test",
197
+ }),
198
+ ])
199
+ assert_nothing_raised do
200
+ d = create_driver(conf)
201
+ assert do
202
+ d.logs.count { |log| log.include?("multiple chunks are competing for a single symlink_path") } == 2
203
+ end
204
+ end
205
+ end
186
206
  end
187
207
 
188
208
  sub_test_case 'fully configured output' do
@@ -264,8 +284,8 @@ class FileOutputTest < Test::Unit::TestCase
264
284
  assert !(Dir.exist?("#{TMP_DIR}/my.data/a"))
265
285
  assert !(Dir.exist?("#{TMP_DIR}/your.data/a"))
266
286
  buffer_files = Dir.entries("#{TMP_DIR}/buf_full").reject{|e| e =~ /^\.+$/ }
267
- assert_equal 2, buffer_files.select{|n| n.end_with?('.meta') }.size
268
- assert_equal 2, buffer_files.select{|n| !n.end_with?('.meta') }.size
287
+ assert_equal 2, buffer_files.count{|n| n.end_with?('.meta') }
288
+ assert_equal 2, buffer_files.count{|n| !n.end_with?('.meta') }
269
289
 
270
290
  m1 = d.instance.metadata('my.data', t1, {"type" => "a"})
271
291
  m2 = d.instance.metadata('your.data', t3, {"type" => "a"})
@@ -314,7 +334,7 @@ class FileOutputTest < Test::Unit::TestCase
314
334
  assert_equal r5, d.formatted[4]
315
335
 
316
336
  read_gunzip = ->(path){
317
- File.open(path){ |fio|
337
+ File.open(path, 'rb'){ |fio|
318
338
  Zlib::GzipReader.new(StringIO.new(fio.read)).read
319
339
  }
320
340
  }
@@ -12,7 +12,8 @@ class ForwardOutputTest < Test::Unit::TestCase
12
12
  FileUtils.rm_rf(TMP_DIR)
13
13
  FileUtils.mkdir_p(TMP_DIR)
14
14
  @d = nil
15
- @target_port = unused_port
15
+ # forward plugin uses TCP and UDP sockets on the same port number
16
+ @target_port = unused_port(protocol: :all)
16
17
  end
17
18
 
18
19
  def teardown
@@ -156,7 +157,14 @@ EOL
156
157
  normal_conf = config_element('match', '**', {}, [
157
158
  config_element('server', '', {'name' => 'test', 'host' => 'unexisting.yaaaaaaaaaaaaaay.host.example.com'})
158
159
  ])
159
- assert_raise SocketError do
160
+
161
+ if Socket.const_defined?(:ResolutionError) # as of Ruby 3.3
162
+ error_class = Socket::ResolutionError
163
+ else
164
+ error_class = SocketError
165
+ end
166
+
167
+ assert_raise error_class do
160
168
  create_driver(normal_conf)
161
169
  end
162
170
 
@@ -165,7 +173,7 @@ EOL
165
173
  ])
166
174
  @d = d = create_driver(conf)
167
175
  expected_log = "failed to resolve node name when configured"
168
- expected_detail = 'server="test" error_class=SocketError'
176
+ expected_detail = "server=\"test\" error_class=#{error_class.name}"
169
177
  logs = d.logs
170
178
  assert{ logs.any?{|log| log.include?(expected_log) && log.include?(expected_detail) } }
171
179
  end
@@ -603,7 +611,6 @@ EOL
603
611
 
604
612
  @d = d = create_driver(config + %[
605
613
  require_ack_response true
606
- ack_response_timeout 1s
607
614
  <buffer tag>
608
615
  flush_mode immediate
609
616
  retry_type periodic
@@ -651,7 +658,6 @@ EOL
651
658
 
652
659
  @d = d = create_driver(config + %[
653
660
  require_ack_response true
654
- ack_response_timeout 10s
655
661
  <buffer tag>
656
662
  flush_mode immediate
657
663
  retry_type periodic
@@ -1241,27 +1247,22 @@ EOL
1241
1247
  target_input_driver = create_target_input_driver(conf: target_config)
1242
1248
  output_conf = config
1243
1249
  d = create_driver(output_conf)
1244
- d.instance_start
1245
1250
 
1246
- begin
1247
- chunk = Fluent::Plugin::Buffer::MemoryChunk.new(Fluent::Plugin::Buffer::Metadata.new(nil, nil, nil))
1248
- mock.proxy(d.instance).socket_create_tcp(TARGET_HOST, @target_port,
1249
- linger_timeout: anything,
1250
- send_timeout: anything,
1251
- recv_timeout: anything,
1252
- connect_timeout: anything
1253
- ) { |sock| mock(sock).close.once; sock }.twice
1251
+ chunk = Fluent::Plugin::Buffer::MemoryChunk.new(Fluent::Plugin::Buffer::Metadata.new(nil, nil, nil))
1252
+ mock.proxy(d.instance).socket_create_tcp(TARGET_HOST, @target_port,
1253
+ linger_timeout: anything,
1254
+ send_timeout: anything,
1255
+ recv_timeout: anything,
1256
+ connect_timeout: anything
1257
+ ) { |sock| mock(sock).close.once; sock }.twice
1254
1258
 
1255
- target_input_driver.run(timeout: 15) do
1256
- d.run(shutdown: false) do
1257
- node = d.instance.nodes.first
1258
- 2.times do
1259
- node.send_data('test', chunk) rescue nil
1260
- end
1259
+ target_input_driver.run(timeout: 15) do
1260
+ d.run do
1261
+ node = d.instance.nodes.first
1262
+ 2.times do
1263
+ node.send_data('test', chunk) rescue nil
1261
1264
  end
1262
1265
  end
1263
- ensure
1264
- d.instance_shutdown
1265
1266
  end
1266
1267
  end
1267
1268
 
@@ -1275,7 +1276,6 @@ EOL
1275
1276
  port #{@target_port}
1276
1277
  </server>
1277
1278
  ])
1278
- d.instance_start
1279
1279
  assert_nothing_raised { d.run }
1280
1280
  end
1281
1281
 
@@ -1287,33 +1287,28 @@ EOL
1287
1287
  keepalive_timeout 2
1288
1288
  ]
1289
1289
  d = create_driver(output_conf)
1290
- d.instance_start
1291
1290
 
1292
- begin
1293
- chunk = Fluent::Plugin::Buffer::MemoryChunk.new(Fluent::Plugin::Buffer::Metadata.new(nil, nil, nil))
1294
- mock.proxy(d.instance).socket_create_tcp(TARGET_HOST, @target_port,
1295
- linger_timeout: anything,
1296
- send_timeout: anything,
1297
- recv_timeout: anything,
1298
- connect_timeout: anything
1299
- ) { |sock| mock(sock).close.once; sock }.once
1291
+ chunk = Fluent::Plugin::Buffer::MemoryChunk.new(Fluent::Plugin::Buffer::Metadata.new(nil, nil, nil))
1292
+ mock.proxy(d.instance).socket_create_tcp(TARGET_HOST, @target_port,
1293
+ linger_timeout: anything,
1294
+ send_timeout: anything,
1295
+ recv_timeout: anything,
1296
+ connect_timeout: anything
1297
+ ) { |sock| mock(sock).close.once; sock }.once
1300
1298
 
1301
- target_input_driver.run(timeout: 15) do
1302
- d.run(shutdown: false) do
1303
- node = d.instance.nodes.first
1304
- 2.times do
1305
- node.send_data('test', chunk) rescue nil
1306
- end
1299
+ target_input_driver.run(timeout: 15) do
1300
+ d.run do
1301
+ node = d.instance.nodes.first
1302
+ 2.times do
1303
+ node.send_data('test', chunk) rescue nil
1307
1304
  end
1308
1305
  end
1309
- ensure
1310
- d.instance_shutdown
1311
1306
  end
1312
1307
  end
1313
1308
 
1314
1309
  test 'create timer of purging obsolete sockets' do
1315
1310
  output_conf = config + %[keepalive true]
1316
- d = create_driver(output_conf)
1311
+ @d = d = create_driver(output_conf)
1317
1312
 
1318
1313
  mock(d.instance).timer_execute(:out_forward_heartbeat_request, 1).once
1319
1314
  mock(d.instance).timer_execute(:out_forward_keep_alived_socket_watcher, 5).once
@@ -1329,7 +1324,6 @@ EOL
1329
1324
  keepalive_timeout 2
1330
1325
  ]
1331
1326
  d = create_driver(output_conf)
1332
- d.instance_start
1333
1327
 
1334
1328
  chunk = Fluent::Plugin::Buffer::MemoryChunk.new(Fluent::Plugin::Buffer::Metadata.new(nil, nil, nil))
1335
1329
  mock.proxy(d.instance).socket_create_tcp(TARGET_HOST, @target_port,
@@ -54,7 +54,7 @@ class TcpOutputTest < Test::Unit::TestCase
54
54
 
55
55
  def setup
56
56
  super
57
- @port = unused_port
57
+ @port = unused_port(protocol: :tcp)
58
58
  end
59
59
 
60
60
  def teardown
@@ -447,25 +447,25 @@ class OutputTest < Test::Unit::TestCase
447
447
  @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
448
448
  validators = @i.placeholder_validators(:path, "/my/path/${tag}/${username}/file.%Y%m%d_%H%M.log")
449
449
  assert_equal 3, validators.size
450
- assert_equal 1, validators.select(&:time?).size
451
- assert_equal 1, validators.select(&:tag?).size
452
- assert_equal 1, validators.select(&:keys?).size
450
+ assert_equal 1, validators.count(&:time?)
451
+ assert_equal 1, validators.count(&:tag?)
452
+ assert_equal 1, validators.count(&:keys?)
453
453
  end
454
454
 
455
455
  test 'returns validators for time, tag and keys when a plugin is configured with these keys even if a template does not have placeholders' do
456
456
  @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time,tag,username', {'timekey' => 60})]))
457
457
  validators = @i.placeholder_validators(:path, "/my/path/file.log")
458
458
  assert_equal 3, validators.size
459
- assert_equal 1, validators.select(&:time?).size
460
- assert_equal 1, validators.select(&:tag?).size
461
- assert_equal 1, validators.select(&:keys?).size
459
+ assert_equal 1, validators.count(&:time?)
460
+ assert_equal 1, validators.count(&:tag?)
461
+ assert_equal 1, validators.count(&:keys?)
462
462
  end
463
463
 
464
464
  test 'returns a validator for time if a template has timestamp placeholders' do
465
465
  @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
466
466
  validators = @i.placeholder_validators(:path, "/my/path/file.%Y-%m-%d.log")
467
467
  assert_equal 1, validators.size
468
- assert_equal 1, validators.select(&:time?).size
468
+ assert_equal 1, validators.count(&:time?)
469
469
  assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.%Y-%m-%d.log' has timestamp placeholders, but chunk key 'time' is not configured") do
470
470
  validators.first.validate!
471
471
  end
@@ -475,7 +475,7 @@ class OutputTest < Test::Unit::TestCase
475
475
  @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {'timekey' => '30'})]))
476
476
  validators = @i.placeholder_validators(:path, "/my/path/to/file.log")
477
477
  assert_equal 1, validators.size
478
- assert_equal 1, validators.select(&:time?).size
478
+ assert_equal 1, validators.count(&:time?)
479
479
  assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/to/file.log' doesn't have timestamp placeholders for timekey 30") do
480
480
  validators.first.validate!
481
481
  end
@@ -485,7 +485,7 @@ class OutputTest < Test::Unit::TestCase
485
485
  @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
486
486
  validators = @i.placeholder_validators(:path, "/my/path/${tag}/file.log")
487
487
  assert_equal 1, validators.size
488
- assert_equal 1, validators.select(&:tag?).size
488
+ assert_equal 1, validators.count(&:tag?)
489
489
  assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${tag}/file.log' has tag placeholders, but chunk key 'tag' is not configured") do
490
490
  validators.first.validate!
491
491
  end
@@ -495,7 +495,7 @@ class OutputTest < Test::Unit::TestCase
495
495
  @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'tag')]))
496
496
  validators = @i.placeholder_validators(:path, "/my/path/file.log")
497
497
  assert_equal 1, validators.size
498
- assert_equal 1, validators.select(&:tag?).size
498
+ assert_equal 1, validators.count(&:tag?)
499
499
  assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have tag placeholder") do
500
500
  validators.first.validate!
501
501
  end
@@ -505,7 +505,7 @@ class OutputTest < Test::Unit::TestCase
505
505
  @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
506
506
  validators = @i.placeholder_validators(:path, "/my/path/${username}/file.${group}.log")
507
507
  assert_equal 1, validators.size
508
- assert_equal 1, validators.select(&:keys?).size
508
+ assert_equal 1, validators.count(&:keys?)
509
509
  assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${username}/file.${group}.log' has placeholders, but chunk keys doesn't have keys group,username") do
510
510
  validators.first.validate!
511
511
  end
@@ -515,7 +515,7 @@ class OutputTest < Test::Unit::TestCase
515
515
  @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'username,group')]))
516
516
  validators = @i.placeholder_validators(:path, "/my/path/file.log")
517
517
  assert_equal 1, validators.size
518
- assert_equal 1, validators.select(&:keys?).size
518
+ assert_equal 1, validators.count(&:keys?)
519
519
  assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have enough placeholders for keys group,username") do
520
520
  validators.first.validate!
521
521
  end