fluentd 1.16.7-x64-mingw32 → 1.17.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/DISCUSSION_TEMPLATE/q-a-japanese.yml +50 -0
- data/.github/DISCUSSION_TEMPLATE/q-a.yml +47 -0
- data/.github/workflows/test-ruby-head.yml +31 -0
- data/.github/workflows/test.yml +2 -9
- data/CHANGELOG.md +34 -42
- data/README.md +3 -1
- data/Rakefile +1 -1
- data/fluentd.gemspec +9 -9
- data/lib/fluent/command/binlog_reader.rb +1 -1
- data/lib/fluent/command/fluentd.rb +1 -1
- data/lib/fluent/config/configure_proxy.rb +2 -2
- data/lib/fluent/config/types.rb +1 -1
- data/lib/fluent/config/yaml_parser/parser.rb +0 -4
- data/lib/fluent/configurable.rb +2 -2
- data/lib/fluent/counter/mutex_hash.rb +1 -1
- data/lib/fluent/fluent_log_event_router.rb +0 -2
- data/lib/fluent/plugin/buf_file.rb +1 -1
- data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
- data/lib/fluent/plugin/buffer/file_single_chunk.rb +2 -3
- data/lib/fluent/plugin/filter_parser.rb +26 -8
- data/lib/fluent/plugin/in_http.rb +18 -53
- data/lib/fluent/plugin/in_tail.rb +34 -2
- data/lib/fluent/plugin/out_file.rb +0 -8
- data/lib/fluent/plugin/out_http.rb +125 -13
- data/lib/fluent/plugin/owned_by_mixin.rb +0 -1
- data/lib/fluent/plugin/parser_json.rb +34 -9
- data/lib/fluent/plugin/parser_msgpack.rb +24 -3
- data/lib/fluent/plugin_helper/metrics.rb +2 -2
- data/lib/fluent/registry.rb +6 -6
- data/lib/fluent/supervisor.rb +1 -1
- data/lib/fluent/test/output_test.rb +1 -1
- data/lib/fluent/unique_id.rb +1 -1
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +3 -28
- data/test/command/test_cat.rb +2 -2
- data/test/command/test_fluentd.rb +10 -57
- data/test/helper.rb +7 -27
- data/test/log/test_console_adapter.rb +10 -3
- data/test/plugin/data/log_numeric/01.log +0 -0
- data/test/plugin/data/log_numeric/02.log +0 -0
- data/test/plugin/data/log_numeric/12.log +0 -0
- data/test/plugin/data/log_numeric/14.log +0 -0
- data/test/plugin/in_tail/test_io_handler.rb +14 -13
- data/test/plugin/in_tail/test_position_file.rb +7 -6
- data/test/plugin/out_forward/test_ack_handler.rb +3 -3
- data/test/plugin/out_forward/test_socket_cache.rb +3 -3
- data/test/plugin/test_in_forward.rb +1 -2
- data/test/plugin/test_in_http.rb +24 -2
- data/test/plugin/test_in_monitor_agent.rb +6 -6
- data/test/plugin/test_in_syslog.rb +18 -25
- data/test/plugin/test_in_tail.rb +153 -4
- data/test/plugin/test_in_tcp.rb +1 -1
- data/test/plugin/test_in_udp.rb +10 -16
- data/test/plugin/test_out_exec_filter.rb +7 -12
- data/test/plugin/test_out_file.rb +2 -22
- data/test/plugin/test_out_forward.rb +3 -2
- data/test/plugin/test_out_http.rb +128 -0
- data/test/plugin/test_out_stream.rb +1 -1
- data/test/plugin/test_owned_by.rb +0 -1
- data/test/plugin/test_parser_json.rb +106 -31
- data/test/plugin/test_parser_msgpack.rb +127 -0
- data/test/plugin/test_storage.rb +0 -1
- data/test/plugin_helper/test_child_process.rb +4 -4
- data/test/plugin_helper/test_http_server_helper.rb +1 -1
- data/test/plugin_helper/test_server.rb +41 -64
- data/test/plugin_helper/test_socket.rb +1 -1
- data/test/test_config.rb +0 -6
- data/test/test_event_router.rb +2 -2
- metadata +90 -21
data/test/plugin/test_in_tail.rb
CHANGED
@@ -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
|
-
|
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",
|
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
|
-
|
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",
|
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
|
},
|
data/test/plugin/test_in_tcp.rb
CHANGED
data/test/plugin/test_in_udp.rb
CHANGED
@@ -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
|
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:
|
275
|
+
d.run(expect_records: 3) do
|
287
276
|
create_udp_socket('127.0.0.1', @port) do |u|
|
288
|
-
|
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:
|
504
|
-
|
505
|
-
|
506
|
-
|
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}
|
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
|
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
|
-
|
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
|
@@ -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
|