fluentd 1.16.7-x64-mingw-ucrt → 1.17.0-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/DISCUSSION_TEMPLATE/q-a-japanese.yml +50 -0
  3. data/.github/DISCUSSION_TEMPLATE/q-a.yml +47 -0
  4. data/.github/workflows/test-ruby-head.yml +31 -0
  5. data/.github/workflows/test.yml +2 -9
  6. data/CHANGELOG.md +34 -42
  7. data/README.md +3 -1
  8. data/Rakefile +1 -1
  9. data/fluentd.gemspec +9 -9
  10. data/lib/fluent/command/binlog_reader.rb +1 -1
  11. data/lib/fluent/command/fluentd.rb +1 -1
  12. data/lib/fluent/config/configure_proxy.rb +2 -2
  13. data/lib/fluent/config/types.rb +1 -1
  14. data/lib/fluent/config/yaml_parser/parser.rb +0 -4
  15. data/lib/fluent/configurable.rb +2 -2
  16. data/lib/fluent/counter/mutex_hash.rb +1 -1
  17. data/lib/fluent/fluent_log_event_router.rb +0 -2
  18. data/lib/fluent/plugin/buf_file.rb +1 -1
  19. data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
  20. data/lib/fluent/plugin/buffer/file_single_chunk.rb +2 -3
  21. data/lib/fluent/plugin/filter_parser.rb +26 -8
  22. data/lib/fluent/plugin/in_http.rb +18 -53
  23. data/lib/fluent/plugin/in_tail.rb +34 -2
  24. data/lib/fluent/plugin/out_file.rb +0 -8
  25. data/lib/fluent/plugin/out_http.rb +125 -13
  26. data/lib/fluent/plugin/owned_by_mixin.rb +0 -1
  27. data/lib/fluent/plugin/parser_json.rb +34 -9
  28. data/lib/fluent/plugin/parser_msgpack.rb +24 -3
  29. data/lib/fluent/plugin_helper/metrics.rb +2 -2
  30. data/lib/fluent/registry.rb +6 -6
  31. data/lib/fluent/supervisor.rb +1 -1
  32. data/lib/fluent/test/output_test.rb +1 -1
  33. data/lib/fluent/unique_id.rb +1 -1
  34. data/lib/fluent/version.rb +1 -1
  35. data/lib/fluent/winsvc.rb +3 -28
  36. data/test/command/test_cat.rb +2 -2
  37. data/test/command/test_fluentd.rb +10 -57
  38. data/test/helper.rb +7 -27
  39. data/test/log/test_console_adapter.rb +10 -3
  40. data/test/plugin/data/log_numeric/01.log +0 -0
  41. data/test/plugin/data/log_numeric/02.log +0 -0
  42. data/test/plugin/data/log_numeric/12.log +0 -0
  43. data/test/plugin/data/log_numeric/14.log +0 -0
  44. data/test/plugin/in_tail/test_io_handler.rb +14 -13
  45. data/test/plugin/in_tail/test_position_file.rb +7 -6
  46. data/test/plugin/out_forward/test_ack_handler.rb +3 -3
  47. data/test/plugin/out_forward/test_socket_cache.rb +3 -3
  48. data/test/plugin/test_in_forward.rb +1 -2
  49. data/test/plugin/test_in_http.rb +24 -2
  50. data/test/plugin/test_in_monitor_agent.rb +6 -6
  51. data/test/plugin/test_in_syslog.rb +18 -25
  52. data/test/plugin/test_in_tail.rb +153 -4
  53. data/test/plugin/test_in_tcp.rb +1 -1
  54. data/test/plugin/test_in_udp.rb +10 -16
  55. data/test/plugin/test_out_exec_filter.rb +7 -12
  56. data/test/plugin/test_out_file.rb +2 -22
  57. data/test/plugin/test_out_forward.rb +3 -2
  58. data/test/plugin/test_out_http.rb +128 -0
  59. data/test/plugin/test_out_stream.rb +1 -1
  60. data/test/plugin/test_owned_by.rb +0 -1
  61. data/test/plugin/test_parser_json.rb +106 -31
  62. data/test/plugin/test_parser_msgpack.rb +127 -0
  63. data/test/plugin/test_storage.rb +0 -1
  64. data/test/plugin_helper/test_child_process.rb +4 -4
  65. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  66. data/test/plugin_helper/test_server.rb +41 -64
  67. data/test/plugin_helper/test_socket.rb +1 -1
  68. data/test/test_config.rb +0 -6
  69. data/test/test_event_router.rb +2 -2
  70. metadata +90 -21
@@ -1538,6 +1538,147 @@ class TailInputTest < Test::Unit::TestCase
1538
1538
  assert_equal(ex_paths - [ex_paths.last], plugin.expand_paths.values.sort_by { |path_ino| path_ino.path })
1539
1539
  end
1540
1540
 
1541
+ sub_test_case "expand_paths with glob" do |data|
1542
+ sub_test_case "extended_glob" do
1543
+ data("curly braces" => [true, "always", "test/plugin/data/log_numeric/{0,1}*.log"],
1544
+ "square brackets" => [true, "always", "test/plugin/data/log_numeric/[0-1][2-4].log"],
1545
+ "asterisk" => [true, "always", "test/plugin/data/log/*.log"],
1546
+ "one character matcher" => [true, "always", "test/plugin/data/log/tes?.log"],
1547
+ )
1548
+ def test_expand_paths_with_use_glob_p_and_almost_set_of_patterns
1549
+ result, option, path = data
1550
+ config = config_element("", "", {
1551
+ "tag" => "tail",
1552
+ "path" => path,
1553
+ "format" => "none",
1554
+ "pos_file" => "#{@tmp_dir}/tail.pos",
1555
+ "read_from_head" => true,
1556
+ "refresh_interval" => 30,
1557
+ "glob_policy" => option,
1558
+ "path_delimiter" => "|",
1559
+ "rotate_wait" => "#{EX_ROTATE_WAIT}s",
1560
+ "follow_inodes" => "#{EX_FOLLOW_INODES}",
1561
+ })
1562
+ plugin = create_driver(config, false).instance
1563
+ assert_equal(result, !!plugin.use_glob?(path))
1564
+ end
1565
+
1566
+ data("curly braces" => [true, false, "extended", "test/plugin/data/log_numeric/{0,1}*.log"],
1567
+ "square brackets" => [false, true, "extended", "test/plugin/data/log_numeric/[0-1][2-4].log"],
1568
+ "asterisk" => [false, true, "extended", "test/plugin/data/log/*.log"],
1569
+ "one character matcher" => [false, true, "extended", "test/plugin/data/log/tes?.log"],
1570
+ )
1571
+ def test_expand_paths_with_use_glob_p
1572
+ emit_exception_p, result, option, path = data
1573
+ config = config_element("", "", {
1574
+ "tag" => "tail",
1575
+ "path" => path,
1576
+ "format" => "none",
1577
+ "pos_file" => "#{@tmp_dir}/tail.pos",
1578
+ "read_from_head" => true,
1579
+ "refresh_interval" => 30,
1580
+ "glob_policy" => option,
1581
+ "rotate_wait" => "#{EX_ROTATE_WAIT}s",
1582
+ "follow_inodes" => "#{EX_FOLLOW_INODES}",
1583
+ })
1584
+ if emit_exception_p
1585
+ assert_raise(Fluent::ConfigError) do
1586
+ plugin = create_driver(config, false).instance
1587
+ end
1588
+ else
1589
+ plugin = create_driver(config, false).instance
1590
+ assert_equal(result, !!plugin.use_glob?(path))
1591
+ end
1592
+ end
1593
+ end
1594
+
1595
+ sub_test_case "only_use_backward_compatible" do
1596
+ data("square brackets" => [false, "backward_compatible", "test/plugin/data/log_numeric/[0-1][2-4].log"],
1597
+ "asterisk" => [true, "backward_compatible", "test/plugin/data/log/*.log"],
1598
+ "one character matcher" => [false, "backward_compatible", "test/plugin/data/log/tes?.log"],
1599
+ )
1600
+ def test_expand_paths_with_use_glob_p
1601
+ result, option, path = data
1602
+ config = config_element("", "", {
1603
+ "tag" => "tail",
1604
+ "path" => path,
1605
+ "format" => "none",
1606
+ "pos_file" => "#{@tmp_dir}/tail.pos",
1607
+ "read_from_head" => true,
1608
+ "refresh_interval" => 30,
1609
+ "glob_policy" => option,
1610
+ "rotate_wait" => "#{EX_ROTATE_WAIT}s",
1611
+ "follow_inodes" => "#{EX_FOLLOW_INODES}",
1612
+ })
1613
+ plugin = create_driver(config, false).instance
1614
+ assert_equal(result, !!plugin.use_glob?(path))
1615
+ end
1616
+ end
1617
+ end
1618
+
1619
+ def ex_config_with_brackets
1620
+ config_element("", "", {
1621
+ "tag" => "tail",
1622
+ "path" => "test/plugin/data/log_numeric/[0-1][2-4].log",
1623
+ "format" => "none",
1624
+ "pos_file" => "#{@tmp_dir}/tail.pos",
1625
+ "read_from_head" => true,
1626
+ "refresh_interval" => 30,
1627
+ "glob_policy" => "extended",
1628
+ "rotate_wait" => "#{EX_ROTATE_WAIT}s",
1629
+ "follow_inodes" => "#{EX_FOLLOW_INODES}",
1630
+ })
1631
+ end
1632
+
1633
+ def test_config_with_always_with_default_delimiter
1634
+ assert_raise(Fluent::ConfigError) do
1635
+ config = config_element("", "", {
1636
+ "tag" => "tail",
1637
+ "path" => "test/plugin/data/log_numeric/[0-1][2-4].log",
1638
+ "format" => "none",
1639
+ "pos_file" => "#{@tmp_dir}/tail.pos",
1640
+ "read_from_head" => true,
1641
+ "refresh_interval" => 30,
1642
+ "glob_policy" => "always",
1643
+ "rotate_wait" => "#{EX_ROTATE_WAIT}s",
1644
+ "follow_inodes" => "#{EX_FOLLOW_INODES}",
1645
+ })
1646
+
1647
+ create_driver(config, false).instance
1648
+ end
1649
+ end
1650
+
1651
+ def test_config_with_always_with_custom_delimiter
1652
+ assert_nothing_raised do
1653
+ config = config_element("", "", {
1654
+ "tag" => "tail",
1655
+ "path" => "test/plugin/data/log_numeric/[0-1][2-4].log",
1656
+ "format" => "none",
1657
+ "pos_file" => "#{@tmp_dir}/tail.pos",
1658
+ "read_from_head" => true,
1659
+ "refresh_interval" => 30,
1660
+ "glob_policy" => "always",
1661
+ "path_delimiter" => "|",
1662
+ "rotate_wait" => "#{EX_ROTATE_WAIT}s",
1663
+ "follow_inodes" => "#{EX_FOLLOW_INODES}",
1664
+ })
1665
+
1666
+ create_driver(config, false).instance
1667
+ end
1668
+ end
1669
+
1670
+ def test_expand_paths_with_brackets
1671
+ expanded_paths = [
1672
+ create_target_info('test/plugin/data/log_numeric/01.log'),
1673
+ create_target_info('test/plugin/data/log_numeric/02.log'),
1674
+ create_target_info('test/plugin/data/log_numeric/12.log'),
1675
+ create_target_info('test/plugin/data/log_numeric/14.log'),
1676
+ ]
1677
+
1678
+ plugin = create_driver(ex_config_with_brackets, false).instance
1679
+ assert_equal(expanded_paths - [expanded_paths.first], plugin.expand_paths.values.sort_by { |path_ino| path_ino.path })
1680
+ end
1681
+
1541
1682
  def test_expand_paths_with_duplicate_configuration
1542
1683
  expanded_paths = [
1543
1684
  create_target_info('test/plugin/data/log/foo/bar.log'),
@@ -3172,7 +3313,9 @@ class TailInputTest < Test::Unit::TestCase
3172
3313
  Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt0", "ab") {|f| f.puts "file3 log2"}
3173
3314
  end
3174
3315
 
3175
- pos_file_inode = tail_watchers[2].pe.read_inode
3316
+ inode_0 = tail_watchers[0]&.ino
3317
+ inode_1 = tail_watchers[1]&.ino
3318
+ inode_2 = tail_watchers[2]&.ino
3176
3319
  record_values = d.events.collect { |event| event[2]["message"] }.sort
3177
3320
  position_entries = []
3178
3321
  Fluent::FileWrapper.open("#{@tmp_dir}/tail.pos", "r") do |f|
@@ -3186,15 +3329,17 @@ class TailInputTest < Test::Unit::TestCase
3186
3329
  {
3187
3330
  record_values: ["file1 log1", "file1 log2", "file2 log1", "file2 log2", "file3 log1", "file3 log2"],
3188
3331
  tail_watcher_paths: ["#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0"],
3332
+ tail_watcher_inodes: [inode_0, inode_1, inode_2],
3189
3333
  tail_watcher_io_handler_opened_statuses: [false, false, false],
3190
3334
  position_entries: [
3191
3335
  # The recorded path is old, but it is no problem. The path is not used when using follow_inodes.
3192
- ["#{@tmp_dir}/tail.txt0", "0000000000000016", pos_file_inode],
3336
+ ["#{@tmp_dir}/tail.txt0", "0000000000000016", inode_2],
3193
3337
  ],
3194
3338
  },
3195
3339
  {
3196
3340
  record_values: record_values,
3197
3341
  tail_watcher_paths: tail_watchers.collect { |tw| tw.path },
3342
+ tail_watcher_inodes: tail_watchers.collect { |tw| tw.ino },
3198
3343
  tail_watcher_io_handler_opened_statuses: tail_watchers.collect { |tw| tw.instance_variable_get(:@io_handler)&.opened? || false },
3199
3344
  position_entries: position_entries
3200
3345
  },
@@ -3249,7 +3394,9 @@ class TailInputTest < Test::Unit::TestCase
3249
3394
  sleep 4
3250
3395
  end
3251
3396
 
3252
- pos_file_inode = tail_watchers[2].pe.read_inode
3397
+ inode_0 = tail_watchers[0]&.ino
3398
+ inode_1 = tail_watchers[1]&.ino
3399
+ inode_2 = tail_watchers[2]&.ino
3253
3400
  record_values = d.events.collect { |event| event[2]["message"] }.sort
3254
3401
  position_entries = []
3255
3402
  Fluent::FileWrapper.open("#{@tmp_dir}/tail.pos", "r") do |f|
@@ -3263,14 +3410,16 @@ class TailInputTest < Test::Unit::TestCase
3263
3410
  {
3264
3411
  record_values: ["file1 log1", "file1 log2", "file2 log1", "file2 log2", "file3 log1", "file3 log2"],
3265
3412
  tail_watcher_paths: ["#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0"],
3413
+ tail_watcher_inodes: [inode_0, inode_1, inode_2],
3266
3414
  tail_watcher_io_handler_opened_statuses: [false, false, false],
3267
3415
  position_entries: [
3268
- ["#{@tmp_dir}/tail.txt0", "0000000000000016", pos_file_inode],
3416
+ ["#{@tmp_dir}/tail.txt0", "0000000000000016", inode_2],
3269
3417
  ],
3270
3418
  },
3271
3419
  {
3272
3420
  record_values: record_values,
3273
3421
  tail_watcher_paths: tail_watchers.collect { |tw| tw.path },
3422
+ tail_watcher_inodes: tail_watchers.collect { |tw| tw.ino },
3274
3423
  tail_watcher_io_handler_opened_statuses: tail_watchers.collect { |tw| tw.instance_variable_get(:@io_handler)&.opened? || false },
3275
3424
  position_entries: position_entries
3276
3425
  },
@@ -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(protocol: :tcp)
8
+ @port = unused_port
9
9
  end
10
10
 
11
11
  def teardown
@@ -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(protocol: :udp)
8
+ @port = unused_port
9
9
  end
10
10
 
11
11
  def teardown
@@ -268,31 +268,25 @@ class UdpInputTest < Test::Unit::TestCase
268
268
 
269
269
  test 'message_length_limit' do
270
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
271
  d = create_driver(base_config + %!
283
272
  format none
284
273
  message_length_limit #{message_length_limit}
285
274
  !)
286
- d.run(expect_records: expected_records.size, timeout: 5) do
275
+ d.run(expect_records: 3) do
287
276
  create_udp_socket('127.0.0.1', @port) do |u|
288
- u.send("0" * 30 + "\n", 0)
289
- 1.upto(3) do |i|
277
+ 3.times do |i|
290
278
  u.send("#{i}" * 40 + "\n", 0)
291
279
  end
292
- u.send("4" * 30 + "\n", 0)
293
280
  end
294
281
  end
295
282
 
283
+ if Fluent.windows?
284
+ expected_records = []
285
+ else
286
+ expected_records = 3.times.collect do |i|
287
+ "#{i}" * message_length_limit
288
+ end
289
+ end
296
290
  actual_records = d.events.collect do |event|
297
291
  event[2]["message"]
298
292
  end
@@ -500,18 +500,10 @@ 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: 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
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}) }
515
507
 
516
508
  assert_equal "2011-01-02 13:14:15\ttest\t0\n", d.formatted[0]
517
509
  assert_equal "2011-01-02 13:14:15\ttest\t1\n", d.formatted[1]
@@ -532,6 +524,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
532
524
  assert_equal pid_list[1], events[1][2]['child_pid']
533
525
  assert_equal pid_list[0], events[2][2]['child_pid']
534
526
  assert_equal pid_list[1], events[3][2]['child_pid']
527
+
528
+ ensure
529
+ d.run(start: false, shutdown: true)
535
530
  end
536
531
 
537
532
  # child process exits per 3 lines
@@ -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}/${tag}/conf_test.current.log",
133
+ 'symlink_path' => "#{TMP_DIR}/conf_test.current.log",
134
134
  'compress' => 'gzip',
135
135
  'recompress' => 'true',
136
136
  }, [
@@ -183,26 +183,6 @@ 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
206
186
  end
207
187
 
208
188
  sub_test_case 'fully configured output' do
@@ -334,7 +314,7 @@ class FileOutputTest < Test::Unit::TestCase
334
314
  assert_equal r5, d.formatted[4]
335
315
 
336
316
  read_gunzip = ->(path){
337
- File.open(path, 'rb'){ |fio|
317
+ File.open(path){ |fio|
338
318
  Zlib::GzipReader.new(StringIO.new(fio.read)).read
339
319
  }
340
320
  }
@@ -12,8 +12,7 @@ class ForwardOutputTest < Test::Unit::TestCase
12
12
  FileUtils.rm_rf(TMP_DIR)
13
13
  FileUtils.mkdir_p(TMP_DIR)
14
14
  @d = nil
15
- # forward plugin uses TCP and UDP sockets on the same port number
16
- @target_port = unused_port(protocol: :all)
15
+ @target_port = unused_port
17
16
  end
18
17
 
19
18
  def teardown
@@ -611,6 +610,7 @@ EOL
611
610
 
612
611
  @d = d = create_driver(config + %[
613
612
  require_ack_response true
613
+ ack_response_timeout 1s
614
614
  <buffer tag>
615
615
  flush_mode immediate
616
616
  retry_type periodic
@@ -658,6 +658,7 @@ EOL
658
658
 
659
659
  @d = d = create_driver(config + %[
660
660
  require_ack_response true
661
+ ack_response_timeout 10s
661
662
  <buffer tag>
662
663
  flush_mode immediate
663
664
  retry_type periodic
@@ -7,6 +7,7 @@ require 'webrick/https'
7
7
  require 'net/http'
8
8
  require 'uri'
9
9
  require 'json'
10
+ require 'aws-sdk-core'
10
11
 
11
12
  # WEBrick's ProcHandler doesn't handle PUT by default
12
13
  module WEBrick::HTTPServlet
@@ -390,6 +391,97 @@ class HTTPOutputTest < Test::Unit::TestCase
390
391
  end
391
392
  end
392
393
 
394
+
395
+ sub_test_case 'aws sigv4 auth' do
396
+ setup do
397
+ @@fake_aws_credentials = Aws::Credentials.new(
398
+ 'fakeaccess',
399
+ 'fakesecret',
400
+ 'fake session token'
401
+ )
402
+ end
403
+
404
+ def server_port
405
+ 19883
406
+ end
407
+
408
+ def test_aws_sigv4_sts_role_arn
409
+ stub(Aws::AssumeRoleCredentials).new do |credentials_provider|
410
+ stub(credentials_provider).credentials {
411
+ @@fake_aws_credentials
412
+ }
413
+ credentials_provider
414
+ end
415
+
416
+ d = create_driver(config + %[
417
+ <auth>
418
+ method aws_sigv4
419
+ aws_service someservice
420
+ aws_region my-region-1
421
+ aws_role_arn arn:aws:iam::123456789012:role/MyRole
422
+ </auth>
423
+ ])
424
+ d.run(default_tag: 'test.http') do
425
+ test_events.each { |event|
426
+ d.feed(event)
427
+ }
428
+ end
429
+
430
+ result = @@result
431
+ assert_equal 'POST', result.method
432
+ assert_equal 'application/x-ndjson', result.content_type
433
+ assert_equal test_events, result.data
434
+ assert_not_empty result.headers
435
+ assert_not_nil result.headers['authorization']
436
+ assert_match /AWS4-HMAC-SHA256 Credential=[a-zA-Z0-9]*\/\d+\/my-region-1\/someservice\/aws4_request/, result.headers['authorization']
437
+ assert_match /SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token/, result.headers['authorization']
438
+ assert_equal @@fake_aws_credentials.session_token, result.headers['x-amz-security-token']
439
+ assert_not_nil result.headers['x-amz-content-sha256']
440
+ assert_not_empty result.headers['x-amz-content-sha256']
441
+ assert_not_nil result.headers['x-amz-security-token']
442
+ assert_not_empty result.headers['x-amz-security-token']
443
+ assert_not_nil result.headers['x-amz-date']
444
+ assert_not_empty result.headers['x-amz-date']
445
+ end
446
+
447
+ def test_aws_sigv4_no_role
448
+ stub(Aws::CredentialProviderChain).new do |provider_chain|
449
+ stub(provider_chain).resolve {
450
+ @@fake_aws_credentials
451
+ }
452
+ provider_chain
453
+ end
454
+ d = create_driver(config + %[
455
+ <auth>
456
+ method aws_sigv4
457
+ aws_service someservice
458
+ aws_region my-region-1
459
+ </auth>
460
+ ])
461
+ d.run(default_tag: 'test.http') do
462
+ test_events.each { |event|
463
+ d.feed(event)
464
+ }
465
+ end
466
+
467
+ result = @@result
468
+ assert_equal 'POST', result.method
469
+ assert_equal 'application/x-ndjson', result.content_type
470
+ assert_equal test_events, result.data
471
+ assert_not_empty result.headers
472
+ assert_not_nil result.headers['authorization']
473
+ assert_match /AWS4-HMAC-SHA256 Credential=[a-zA-Z0-9]*\/\d+\/my-region-1\/someservice\/aws4_request/, result.headers['authorization']
474
+ assert_match /SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token/, result.headers['authorization']
475
+ assert_equal @@fake_aws_credentials.session_token, result.headers['x-amz-security-token']
476
+ assert_not_nil result.headers['x-amz-content-sha256']
477
+ assert_not_empty result.headers['x-amz-content-sha256']
478
+ assert_not_nil result.headers['x-amz-security-token']
479
+ assert_not_empty result.headers['x-amz-security-token']
480
+ assert_not_nil result.headers['x-amz-date']
481
+ assert_not_empty result.headers['x-amz-date']
482
+ end
483
+ end
484
+
393
485
  sub_test_case 'HTTPS' do
394
486
  def server_port
395
487
  19882
@@ -426,4 +518,40 @@ class HTTPOutputTest < Test::Unit::TestCase
426
518
  assert_not_empty result.headers
427
519
  end
428
520
  end
521
+
522
+ sub_test_case 'connection_reuse' do
523
+ def server_port
524
+ 19883
525
+ end
526
+
527
+ def test_connection_recreation
528
+ d = create_driver(%[
529
+ endpoint http://127.0.0.1:#{server_port}/test
530
+ reuse_connections true
531
+ ])
532
+
533
+ d.run(default_tag: 'test.http', shutdown: false) do
534
+ d.feed(test_events[0])
535
+ end
536
+
537
+ data = @@result.data
538
+
539
+ # Restart server to simulate connection loss
540
+ @@http_server_thread.kill
541
+ @@http_server_thread.join
542
+ @@http_server_thread = Thread.new do
543
+ run_http_server
544
+ end
545
+
546
+ d.run(default_tag: 'test.http') do
547
+ d.feed(test_events[1])
548
+ end
549
+
550
+ result = @@result
551
+ assert_equal 'POST', result.method
552
+ assert_equal 'application/x-ndjson', result.content_type
553
+ assert_equal test_events, data.concat(result.data)
554
+ assert_not_empty result.headers
555
+ end
556
+ end
429
557
  end
@@ -54,7 +54,7 @@ class TcpOutputTest < Test::Unit::TestCase
54
54
 
55
55
  def setup
56
56
  super
57
- @port = unused_port(protocol: :tcp)
57
+ @port = unused_port
58
58
  end
59
59
 
60
60
  def teardown
@@ -26,7 +26,6 @@ class OwnedByMixinTest < Test::Unit::TestCase
26
26
 
27
27
  assert_equal parent.object_id, child.owner.object_id
28
28
 
29
- assert child.instance_eval{ @_plugin_id_configured }
30
29
  assert_equal 'my_parent_id', child.instance_eval{ @_plugin_id }
31
30
 
32
31
  assert_equal Fluent::Log::LEVEL_TRACE, child.log.level