fluentd 1.12.0.rc2 → 1.12.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.deepsource.toml +13 -0
- data/.github/ISSUE_TEMPLATE/config.yml +2 -2
- data/.github/workflows/linux-test.yaml +36 -0
- data/.github/workflows/macos-test.yaml +30 -0
- data/.github/workflows/windows-test.yaml +35 -0
- data/.gitlab-ci.yml +41 -19
- data/CHANGELOG.md +157 -0
- data/MAINTAINERS.md +5 -2
- data/README.md +7 -4
- data/fluentd.gemspec +5 -4
- data/lib/fluent/command/bundler_injection.rb +1 -1
- data/lib/fluent/command/ca_generate.rb +6 -3
- data/lib/fluent/command/cat.rb +0 -1
- data/lib/fluent/command/fluentd.rb +4 -0
- data/lib/fluent/command/plugin_config_formatter.rb +16 -1
- data/lib/fluent/command/plugin_generator.rb +31 -1
- data/lib/fluent/compat/parser.rb +2 -2
- data/lib/fluent/config/section.rb +2 -2
- data/lib/fluent/config/types.rb +2 -2
- data/lib/fluent/event.rb +3 -13
- data/lib/fluent/load.rb +0 -1
- data/lib/fluent/plugin/file_wrapper.rb +39 -3
- data/lib/fluent/plugin/formatter_ltsv.rb +2 -2
- data/lib/fluent/plugin/in_http.rb +1 -1
- data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
- data/lib/fluent/plugin/in_tail.rb +35 -15
- data/lib/fluent/plugin/in_tail/position_file.rb +15 -1
- data/lib/fluent/plugin/in_tcp.rb +1 -0
- data/lib/fluent/plugin/out_copy.rb +18 -5
- data/lib/fluent/plugin/out_exec_filter.rb +3 -3
- data/lib/fluent/plugin/out_forward.rb +61 -28
- data/lib/fluent/plugin/out_http.rb +9 -2
- data/lib/fluent/plugin/output.rb +11 -9
- data/lib/fluent/plugin/parser_csv.rb +2 -2
- data/lib/fluent/plugin/parser_syslog.rb +2 -2
- data/lib/fluent/plugin/storage_local.rb +4 -4
- data/lib/fluent/plugin_helper/inject.rb +4 -2
- data/lib/fluent/plugin_helper/server.rb +4 -2
- data/lib/fluent/plugin_helper/socket_option.rb +2 -2
- data/lib/fluent/supervisor.rb +13 -5
- data/lib/fluent/system_config.rb +2 -1
- data/lib/fluent/time.rb +58 -1
- data/lib/fluent/version.rb +1 -1
- data/templates/new_gem/fluent-plugin.gemspec.erb +3 -3
- data/templates/plugin_config_formatter/param.md-table.erb +10 -0
- data/test/command/test_fluentd.rb +38 -0
- data/test/command/test_plugin_config_formatter.rb +67 -0
- data/test/config/test_configurable.rb +1 -1
- data/test/plugin/in_tail/test_position_file.rb +59 -5
- data/test/plugin/test_file_wrapper.rb +105 -0
- data/test/plugin/test_in_exec.rb +1 -1
- data/test/plugin/test_in_tail.rb +87 -26
- data/test/plugin/test_out_copy.rb +87 -0
- data/test/plugin/test_out_forward.rb +94 -6
- data/test/plugin/test_out_http.rb +20 -1
- data/test/plugin/test_output.rb +15 -3
- data/test/plugin/test_output_as_buffered_backup.rb +2 -0
- data/test/plugin/test_parser_csv.rb +14 -0
- data/test/plugin/test_parser_syslog.rb +16 -2
- data/test/plugin/test_sd_file.rb +1 -1
- data/test/plugin_helper/service_discovery/test_manager.rb +1 -1
- data/test/plugin_helper/test_child_process.rb +5 -2
- data/test/plugin_helper/test_http_server_helper.rb +4 -2
- data/test/plugin_helper/test_inject.rb +29 -0
- data/test/plugin_helper/test_server.rb +26 -7
- data/test/test_event.rb +16 -0
- data/test/test_formatter.rb +30 -0
- data/test/test_output.rb +2 -2
- data/test/test_supervisor.rb +31 -0
- data/test/test_time_parser.rb +109 -0
- metadata +36 -31
- data/.travis.yml +0 -77
- data/appveyor.yml +0 -31
data/lib/fluent/system_config.rb
CHANGED
@@ -27,7 +27,7 @@ module Fluent
|
|
27
27
|
:log_event_verbose, :ignore_repeated_log_interval, :ignore_same_log_interval,
|
28
28
|
:without_source, :rpc_endpoint, :enable_get_dump, :process_name,
|
29
29
|
:file_permission, :dir_permission, :counter_server, :counter_client,
|
30
|
-
:strict_config_value, :enable_msgpack_time_support
|
30
|
+
:strict_config_value, :enable_msgpack_time_support, :disable_shared_socket
|
31
31
|
]
|
32
32
|
|
33
33
|
config_param :workers, :integer, default: 1
|
@@ -45,6 +45,7 @@ module Fluent
|
|
45
45
|
config_param :process_name, :string, default: nil
|
46
46
|
config_param :strict_config_value, :bool, default: nil
|
47
47
|
config_param :enable_msgpack_time_support, :bool, default: nil
|
48
|
+
config_param :disable_shared_socket, :bool, default: nil
|
48
49
|
config_param :file_permission, default: nil do |v|
|
49
50
|
v.to_i(8)
|
50
51
|
end
|
data/lib/fluent/time.rb
CHANGED
@@ -50,6 +50,7 @@ module Fluent
|
|
50
50
|
def to_int
|
51
51
|
@sec
|
52
52
|
end
|
53
|
+
alias :to_i :to_int
|
53
54
|
|
54
55
|
def to_f
|
55
56
|
@sec + @nsec / 1_000_000_000.0
|
@@ -131,13 +132,14 @@ module Fluent
|
|
131
132
|
end
|
132
133
|
|
133
134
|
module TimeMixin
|
134
|
-
TIME_TYPES = ['string', 'unixtime', 'float']
|
135
|
+
TIME_TYPES = ['string', 'unixtime', 'float', 'mixed']
|
135
136
|
|
136
137
|
TIME_PARAMETERS = [
|
137
138
|
[:time_format, :string, {default: nil}],
|
138
139
|
[:localtime, :bool, {default: true}], # UTC if :localtime is false and :timezone is nil
|
139
140
|
[:utc, :bool, {default: false}], # to turn :localtime false
|
140
141
|
[:timezone, :string, {default: nil}],
|
142
|
+
[:time_format_fallbacks, :array, {default: []}], # try time_format, then try fallbacks
|
141
143
|
]
|
142
144
|
TIME_FULL_PARAMETERS = [
|
143
145
|
# To avoid to define :time_type twice (in plugin_helper/inject)
|
@@ -169,6 +171,12 @@ module Fluent
|
|
169
171
|
raise Fluent::ConfigError, "both of utc and localtime are specified, use only one of them"
|
170
172
|
end
|
171
173
|
|
174
|
+
if conf.has_key?('time_type') and @time_type == :mixed
|
175
|
+
if @time_format.nil? and @time_format_fallbacks.empty?
|
176
|
+
raise Fluent::ConfigError, "time_type is :mixed but time_format and time_format_fallbacks is empty."
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
172
180
|
Fluent::Timezone.validate!(@timezone) if @timezone
|
173
181
|
end
|
174
182
|
end
|
@@ -179,6 +187,7 @@ module Fluent
|
|
179
187
|
end
|
180
188
|
|
181
189
|
def time_parser_create(type: @time_type, format: @time_format, timezone: @timezone, force_localtime: false)
|
190
|
+
return MixedTimeParser.new(type, format, @localtime, timezone, @utc, force_localtime, @time_format_fallbacks) if type == :mixed
|
182
191
|
return NumericTimeParser.new(type) if type != :string
|
183
192
|
return TimeParser.new(format, true, nil) if force_localtime
|
184
193
|
|
@@ -451,4 +460,52 @@ module Fluent
|
|
451
460
|
end
|
452
461
|
end
|
453
462
|
end
|
463
|
+
|
464
|
+
# MixedTimeParser is available when time_type is set to :mixed
|
465
|
+
#
|
466
|
+
# Use Case 1: primary format is specified explicitly in time_format
|
467
|
+
# time_type mixed
|
468
|
+
# time_format %iso8601
|
469
|
+
# time_format_fallbacks unixtime
|
470
|
+
# Use Case 2: time_format is omitted
|
471
|
+
# time_type mixed
|
472
|
+
# time_format_fallbacks %iso8601, unixtime
|
473
|
+
#
|
474
|
+
class MixedTimeParser < TimeParser # to include TimeParseError
|
475
|
+
def initialize(type, format = nil, localtime = nil, timezone = nil, utc = nil, force_localtime = nil, fallbacks = [])
|
476
|
+
@parsers = []
|
477
|
+
fallbacks.unshift(format).each do |fallback|
|
478
|
+
next unless fallback
|
479
|
+
case fallback
|
480
|
+
when 'unixtime', 'float'
|
481
|
+
@parsers << NumericTimeParser.new(fallback, localtime, timezone)
|
482
|
+
else
|
483
|
+
if force_localtime
|
484
|
+
@parsers << TimeParser.new(fallback, true, nil)
|
485
|
+
else
|
486
|
+
localtime = localtime && (timezone.nil? && !utc)
|
487
|
+
@parsers << TimeParser.new(fallback, localtime, timezone)
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
def parse(value)
|
494
|
+
@parsers.each do |parser|
|
495
|
+
begin
|
496
|
+
Float(value) if parser.class == Fluent::NumericTimeParser
|
497
|
+
rescue
|
498
|
+
next
|
499
|
+
end
|
500
|
+
begin
|
501
|
+
return parser.parse(value)
|
502
|
+
rescue
|
503
|
+
# skip TimeParseError
|
504
|
+
end
|
505
|
+
end
|
506
|
+
fallback_class = @parsers.collect do |parser| parser.class end.join(",")
|
507
|
+
raise TimeParseError, "invalid time format: value = #{value}, even though fallbacks: #{fallback_class}"
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
454
511
|
end
|
data/lib/fluent/version.rb
CHANGED
@@ -20,8 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.test_files = test_files
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_development_dependency "bundler", "~>
|
24
|
-
spec.add_development_dependency "rake", "~>
|
25
|
-
spec.add_development_dependency "test-unit", "~>
|
23
|
+
spec.add_development_dependency "bundler", "~> <%= bundler_version %>"
|
24
|
+
spec.add_development_dependency "rake", "~> <%= rake_version %>"
|
25
|
+
spec.add_development_dependency "test-unit", "~> <%= test_unit_version %>"
|
26
26
|
spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
|
27
27
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%-
|
2
|
+
type = config[:type]
|
3
|
+
required_label = config[:required] ? "required" : "optional"
|
4
|
+
default = config[:default]
|
5
|
+
alias_name = config[:alias]
|
6
|
+
deprecated = config[:deprecated]
|
7
|
+
obsoleted = config[:obsoleted]
|
8
|
+
description = config[:desc]
|
9
|
+
-%>
|
10
|
+
|<%= name %>|<%= type %> (<%= required_label %>)|<%= description %><%- if type == :enum -%> (<%= config[:list].map{|x| "`#{x}`"}.join(", ") %>)<%- end -%><%- if alias_name -%><br>Alias: <%= alias_name %><%- end -%><%- if deprecated -%><br>Deprecated: <%= deprecated %><%- end -%><%- if obsoleted -%><br>Obsoleted: <%= :obsoleted %><%- end -%>|<%- if default -%>`<%= default %>`<%- end -%>|
|
@@ -878,6 +878,8 @@ CONF
|
|
878
878
|
end
|
879
879
|
|
880
880
|
test "without RUBYOPT" do
|
881
|
+
saved_ruby_opt = ENV["RUBYOPT"]
|
882
|
+
ENV["RUBYOPT"] = nil
|
881
883
|
conf = <<CONF
|
882
884
|
<source>
|
883
885
|
@type dummy
|
@@ -889,6 +891,8 @@ CONF
|
|
889
891
|
CONF
|
890
892
|
conf_path = create_conf_file('rubyopt_test.conf', conf)
|
891
893
|
assert_log_matches(create_cmdline(conf_path), '-Eascii-8bit:ascii-8bit')
|
894
|
+
ensure
|
895
|
+
ENV["RUBYOPT"] = saved_ruby_opt
|
892
896
|
end
|
893
897
|
|
894
898
|
test 'invalid values are set to RUBYOPT' do
|
@@ -912,6 +916,8 @@ CONF
|
|
912
916
|
|
913
917
|
# https://github.com/fluent/fluentd/issues/2915
|
914
918
|
test "ruby path contains spaces" do
|
919
|
+
saved_ruby_opt = ENV["RUBYOPT"]
|
920
|
+
ENV["RUBYOPT"] = nil
|
915
921
|
conf = <<CONF
|
916
922
|
<source>
|
917
923
|
@type dummy
|
@@ -940,6 +946,8 @@ CONF
|
|
940
946
|
'spawn command to main:',
|
941
947
|
'-Eascii-8bit:ascii-8bit'
|
942
948
|
)
|
949
|
+
ensure
|
950
|
+
ENV["RUBYOPT"] = saved_ruby_opt
|
943
951
|
end
|
944
952
|
|
945
953
|
test 'success to start workers when file buffer is configured in non-workers way only for specific worker' do
|
@@ -1065,4 +1073,34 @@ CONF
|
|
1065
1073
|
"secret xxxxxx", patterns_not_match: ["secret secret0", "secret secret1"])
|
1066
1074
|
end
|
1067
1075
|
end
|
1076
|
+
|
1077
|
+
sub_test_case 'sahred socket options' do
|
1078
|
+
test 'enable shared socket by default' do
|
1079
|
+
conf = ""
|
1080
|
+
conf_path = create_conf_file('empty.conf', conf)
|
1081
|
+
assert File.exist?(conf_path)
|
1082
|
+
assert_log_matches(create_cmdline(conf_path),
|
1083
|
+
patterns_not_match: ["shared socket for multiple workers is disabled"])
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
test 'disable shared socket by command line option' do
|
1087
|
+
conf = ""
|
1088
|
+
conf_path = create_conf_file('empty.conf', conf)
|
1089
|
+
assert File.exist?(conf_path)
|
1090
|
+
assert_log_matches(create_cmdline(conf_path, "--disable-shared-socket"),
|
1091
|
+
"shared socket for multiple workers is disabled",)
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
test 'disable shared socket by system config' do
|
1095
|
+
conf = <<CONF
|
1096
|
+
<system>
|
1097
|
+
disable_shared_socket
|
1098
|
+
</system>
|
1099
|
+
CONF
|
1100
|
+
conf_path = create_conf_file('empty.conf', conf)
|
1101
|
+
assert File.exist?(conf_path)
|
1102
|
+
assert_log_matches(create_cmdline(conf_path, "--disable-shared-socket"),
|
1103
|
+
"shared socket for multiple workers is disabled",)
|
1104
|
+
end
|
1105
|
+
end
|
1068
1106
|
end
|
@@ -225,6 +225,30 @@ TEXT
|
|
225
225
|
path to something
|
226
226
|
|
227
227
|
|
228
|
+
TEXT
|
229
|
+
assert_equal(expected, dumped_config)
|
230
|
+
end
|
231
|
+
|
232
|
+
test "input simple (table)" do
|
233
|
+
dumped_config = capture_stdout do
|
234
|
+
FluentPluginConfigFormatter.new(["--format=markdown", "--table", "input", "simple"]).call
|
235
|
+
end
|
236
|
+
expected = <<TEXT
|
237
|
+
## Plugin helpers
|
238
|
+
|
239
|
+
* [inject](https://docs.fluentd.org/v/1.0/plugin-helper-overview/api-plugin-helper-inject)
|
240
|
+
* [compat_parameters](https://docs.fluentd.org/v/1.0/plugin-helper-overview/api-plugin-helper-compat_parameters)
|
241
|
+
|
242
|
+
* See also: [Input Plugin Overview](https://docs.fluentd.org/v/1.0/input#overview)
|
243
|
+
|
244
|
+
## TestFluentPluginConfigFormatter::SimpleInput
|
245
|
+
|
246
|
+
### Configuration
|
247
|
+
|
248
|
+
|parameter|type|description|default|
|
249
|
+
|---|---|---|---|
|
250
|
+
|path|string (required)|path to something||
|
251
|
+
|
228
252
|
TEXT
|
229
253
|
assert_equal(expected, dumped_config)
|
230
254
|
end
|
@@ -298,6 +322,49 @@ Default value: `normal`.
|
|
298
322
|
|
299
323
|
|
300
324
|
|
325
|
+
TEXT
|
326
|
+
assert_equal(expected, dumped_config)
|
327
|
+
end
|
328
|
+
|
329
|
+
test "output complex (table)" do
|
330
|
+
dumped_config = capture_stdout do
|
331
|
+
FluentPluginConfigFormatter.new(["--format=markdown", "--table", "output", "complex"]).call
|
332
|
+
end
|
333
|
+
expected = <<TEXT
|
334
|
+
## Plugin helpers
|
335
|
+
|
336
|
+
* [inject](https://docs.fluentd.org/v/1.0/plugin-helper-overview/api-plugin-helper-inject)
|
337
|
+
* [compat_parameters](https://docs.fluentd.org/v/1.0/plugin-helper-overview/api-plugin-helper-compat_parameters)
|
338
|
+
|
339
|
+
* See also: [Output Plugin Overview](https://docs.fluentd.org/v/1.0/output#overview)
|
340
|
+
|
341
|
+
## TestFluentPluginConfigFormatter::ComplexOutput
|
342
|
+
|
343
|
+
|
344
|
+
### \\<authentication\\> section (required) (single)
|
345
|
+
|
346
|
+
### Configuration
|
347
|
+
|
348
|
+
|parameter|type|description|default|
|
349
|
+
|---|---|---|---|
|
350
|
+
|username|string (required)|username||
|
351
|
+
|password|string (required)|password||
|
352
|
+
|
353
|
+
|
354
|
+
### \\<parent\\> section (optional) (multiple)
|
355
|
+
|
356
|
+
|
357
|
+
#### \\<child\\> section (optional) (multiple)
|
358
|
+
|
359
|
+
### Configuration
|
360
|
+
|
361
|
+
|parameter|type|description|default|
|
362
|
+
|---|---|---|---|
|
363
|
+
|names|array (required)|names||
|
364
|
+
|difficulty|enum (optional)|difficulty (`easy`, `normal`, `hard`)|`normal`|
|
365
|
+
|
366
|
+
|
367
|
+
|
301
368
|
TEXT
|
302
369
|
assert_equal(expected, dumped_config)
|
303
370
|
end
|
@@ -1453,7 +1453,7 @@ module Fluent::Config
|
|
1453
1453
|
@example = ConfigurableSpec::ExampleWithSkipAccessor.new
|
1454
1454
|
@example.configure(config_element('ROOT'))
|
1455
1455
|
assert_equal 'example7', @example.instance_variable_get(:@name)
|
1456
|
-
assert_raise NoMethodError
|
1456
|
+
assert_raise NoMethodError do
|
1457
1457
|
@example.name
|
1458
1458
|
end
|
1459
1459
|
end
|
@@ -85,7 +85,7 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
85
85
|
assert_equal 5, lines.size
|
86
86
|
end
|
87
87
|
|
88
|
-
test 'update seek
|
88
|
+
test 'update seek position of remained position entry' do
|
89
89
|
pf = Fluent::Plugin::TailInput::PositionFile.new(@file, false, {}, **{logger: $log})
|
90
90
|
target_info1 = Fluent::Plugin::TailInput::TargetInfo.new('path1', -1)
|
91
91
|
target_info2 = Fluent::Plugin::TailInput::TargetInfo.new('path2', -1)
|
@@ -147,7 +147,7 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
147
147
|
write_data(@file, TEST_CONTENT)
|
148
148
|
pf = Fluent::Plugin::TailInput::PositionFile.load(@file, false, {}, **{logger: $log})
|
149
149
|
|
150
|
-
valid_target_info = Fluent::Plugin::TailInput::TargetInfo.new('valid_path',
|
150
|
+
valid_target_info = Fluent::Plugin::TailInput::TargetInfo.new('valid_path', File.stat(@file).ino)
|
151
151
|
f = pf[valid_target_info]
|
152
152
|
assert_equal Fluent::Plugin::TailInput::FilePositionEntry, f.class
|
153
153
|
assert_equal 2, f.read_pos
|
@@ -177,7 +177,7 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
177
177
|
assert_equal 0, f.read_inode
|
178
178
|
assert_equal 0, f.read_pos
|
179
179
|
|
180
|
-
pf[Fluent::Plugin::TailInput::TargetInfo.new('valid_path',
|
180
|
+
pf[Fluent::Plugin::TailInput::TargetInfo.new('valid_path', File.stat(@file).ino)].update(1, 2)
|
181
181
|
|
182
182
|
f = pf[Fluent::Plugin::TailInput::TargetInfo.new('nonexist_path', -1)]
|
183
183
|
assert_equal 0, f.read_inode
|
@@ -193,7 +193,7 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
193
193
|
test 'deletes entry by path' do
|
194
194
|
write_data(@file, TEST_CONTENT)
|
195
195
|
pf = Fluent::Plugin::TailInput::PositionFile.load(@file, false, {}, logger: $log)
|
196
|
-
inode1 =
|
196
|
+
inode1 = File.stat(@file).ino
|
197
197
|
target_info1 = Fluent::Plugin::TailInput::TargetInfo.new('valid_path', inode1)
|
198
198
|
p1 = pf[target_info1]
|
199
199
|
assert_equal Fluent::Plugin::TailInput::FilePositionEntry, p1.class
|
@@ -201,7 +201,7 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
201
201
|
pf.unwatch(target_info1)
|
202
202
|
assert_equal p1.read_pos, Fluent::Plugin::TailInput::PositionFile::UNWATCHED_POSITION
|
203
203
|
|
204
|
-
inode2 =
|
204
|
+
inode2 = File.stat(@file).ino
|
205
205
|
target_info2 = Fluent::Plugin::TailInput::TargetInfo.new('valid_path', inode2)
|
206
206
|
p2 = pf[target_info2]
|
207
207
|
assert_equal Fluent::Plugin::TailInput::FilePositionEntry, p2.class
|
@@ -282,4 +282,58 @@ class IntailPositionFileTest < Test::Unit::TestCase
|
|
282
282
|
assert_equal 2, f.read_inode
|
283
283
|
end
|
284
284
|
end
|
285
|
+
|
286
|
+
sub_test_case "TargetInfo equality rules" do
|
287
|
+
sub_test_case "== operator" do
|
288
|
+
def test_equal
|
289
|
+
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
290
|
+
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1235)
|
291
|
+
|
292
|
+
assert_equal t1, t2
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_not_equal
|
296
|
+
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
297
|
+
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test2", 1234)
|
298
|
+
|
299
|
+
assert_not_equal t1, t2
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
sub_test_case "eql? method" do
|
304
|
+
def test_eql?
|
305
|
+
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
306
|
+
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test", 5321)
|
307
|
+
|
308
|
+
assert do
|
309
|
+
t1.eql? t2
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_not_eql?
|
314
|
+
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test2", 1234)
|
315
|
+
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test3", 1234)
|
316
|
+
|
317
|
+
assert do
|
318
|
+
!t1.eql? t2
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
sub_test_case "hash" do
|
324
|
+
def test_equal
|
325
|
+
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
326
|
+
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test", 7321)
|
327
|
+
|
328
|
+
assert_equal t1.hash, t2.hash
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_not_equal
|
332
|
+
t1 = Fluent::Plugin::TailInput::TargetInfo.new("test", 1234)
|
333
|
+
t2 = Fluent::Plugin::TailInput::TargetInfo.new("test2", 1234)
|
334
|
+
|
335
|
+
assert_not_equal t1.hash, t2.hash
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
285
339
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'fluent/plugin/file_wrapper'
|
3
|
+
|
4
|
+
class FileWrapperTest < Test::Unit::TestCase
|
5
|
+
require 'windows/file'
|
6
|
+
require 'windows/error'
|
7
|
+
include Windows::File
|
8
|
+
include Windows::Error
|
9
|
+
|
10
|
+
TMP_DIR = File.dirname(__FILE__) + "/../tmp/file_wrapper#{ENV['TEST_ENV_NUMBER']}"
|
11
|
+
|
12
|
+
def setup
|
13
|
+
FileUtils.mkdir_p(TMP_DIR)
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
FileUtils.rm_rf(TMP_DIR)
|
18
|
+
end
|
19
|
+
|
20
|
+
sub_test_case 'Win32Error' do
|
21
|
+
test 'equal' do
|
22
|
+
assert_equal(Fluent::Win32Error.new(ERROR_SHARING_VIOLATION, "message"),
|
23
|
+
Fluent::Win32Error.new(ERROR_SHARING_VIOLATION, "message"))
|
24
|
+
end
|
25
|
+
|
26
|
+
test 'different error code' do
|
27
|
+
assert_not_equal(Fluent::Win32Error.new(ERROR_FILE_NOT_FOUND),
|
28
|
+
Fluent::Win32Error.new(ERROR_SHARING_VIOLATION))
|
29
|
+
end
|
30
|
+
|
31
|
+
test 'different error message' do
|
32
|
+
assert_not_equal(Fluent::Win32Error.new(ERROR_FILE_NOT_FOUND, "message1"),
|
33
|
+
Fluent::Win32Error.new(ERROR_FILE_NOT_FOUND, "message2"))
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'different class' do
|
37
|
+
assert_not_equal(Errno::EPIPE,
|
38
|
+
Fluent::Win32Error.new(ERROR_SHARING_VIOLATION))
|
39
|
+
end
|
40
|
+
|
41
|
+
test 'ERROR_SHARING_VIOLATION message' do
|
42
|
+
assert_equal(Fluent::Win32Error.new(ERROR_SHARING_VIOLATION).message,
|
43
|
+
"Fluent::Win32Error: code: 32, The process cannot access the file because it is being used by another process.")
|
44
|
+
end
|
45
|
+
|
46
|
+
test 'ERROR_SHARING_VIOLATION with a message' do
|
47
|
+
assert_equal(Fluent::Win32Error.new(ERROR_SHARING_VIOLATION, "cannot open the file").message,
|
48
|
+
"Fluent::Win32Error: code: 32, The process cannot access the file because it is being used by another process." +
|
49
|
+
" - cannot open the file")
|
50
|
+
end
|
51
|
+
|
52
|
+
test 'to_s' do
|
53
|
+
assert_equal("Fluent::Win32Error: code: 32, The process cannot access the file because it is being used by another process. - C:\file.txt",
|
54
|
+
Fluent::Win32Error.new(ERROR_SHARING_VIOLATION, "C:\file.txt").to_s)
|
55
|
+
end
|
56
|
+
|
57
|
+
test 'inspect' do
|
58
|
+
assert_equal("#<Fluent::Win32Error: code: 32, The process cannot access the file because it is being used by another process. - C:\file.txt>",
|
59
|
+
Fluent::Win32Error.new(ERROR_SHARING_VIOLATION, "C:\file.txt").inspect)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
sub_test_case 'WindowsFile exceptions' do
|
64
|
+
test 'nothing raised' do
|
65
|
+
begin
|
66
|
+
path = "#{TMP_DIR}/test_windows_file.txt"
|
67
|
+
file1 = file2 = nil
|
68
|
+
file1 = File.open(path, "wb") do |f|
|
69
|
+
end
|
70
|
+
assert_nothing_raised do
|
71
|
+
file2 = Fluent::WindowsFile.new(path)
|
72
|
+
ensure
|
73
|
+
file2.close
|
74
|
+
end
|
75
|
+
ensure
|
76
|
+
file1.close if file1
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
test 'Errno::ENOENT raised' do
|
81
|
+
path = "#{TMP_DIR}/nofile.txt"
|
82
|
+
file = nil
|
83
|
+
assert_raise(Errno::ENOENT) do
|
84
|
+
file = Fluent::WindowsFile.new(path)
|
85
|
+
ensure
|
86
|
+
file.close if file
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
test 'ERROR_SHARING_VIOLATION raised' do
|
91
|
+
begin
|
92
|
+
path = "#{TMP_DIR}/test_windows_file.txt"
|
93
|
+
file1 = file2 = nil
|
94
|
+
file1 = File.open(path, "wb")
|
95
|
+
assert_raise(Fluent::Win32Error.new(ERROR_SHARING_VIOLATION, path)) do
|
96
|
+
file2 = Fluent::WindowsFile.new(path, 'r', FILE_SHARE_READ)
|
97
|
+
ensure
|
98
|
+
file2.close if file2
|
99
|
+
end
|
100
|
+
ensure
|
101
|
+
file1.close if file1
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end if Fluent.windows?
|