fluentd 0.14.1 → 0.14.2

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 (129) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +110 -1
  3. data/Rakefile +5 -1
  4. data/appveyor.yml +7 -1
  5. data/example/in_forward.conf +4 -0
  6. data/lib/fluent/compat/exec_util.rb +129 -0
  7. data/lib/fluent/compat/file_util.rb +54 -0
  8. data/lib/fluent/compat/filter.rb +21 -3
  9. data/lib/fluent/compat/formatter.rb +4 -2
  10. data/lib/fluent/compat/formatter_utils.rb +85 -0
  11. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +60 -0
  12. data/lib/fluent/compat/input.rb +1 -3
  13. data/lib/fluent/compat/output.rb +95 -39
  14. data/lib/fluent/compat/parser.rb +17 -0
  15. data/lib/fluent/compat/parser_utils.rb +40 -0
  16. data/lib/fluent/compat/socket_util.rb +165 -0
  17. data/lib/fluent/compat/string_util.rb +34 -0
  18. data/lib/fluent/{test/driver/owner.rb → compat/structured_format_mixin.rb} +5 -11
  19. data/lib/fluent/config/element.rb +2 -2
  20. data/lib/fluent/configurable.rb +2 -1
  21. data/lib/fluent/event.rb +61 -7
  22. data/lib/fluent/event_router.rb +1 -1
  23. data/lib/fluent/plugin.rb +7 -7
  24. data/lib/fluent/plugin/buf_file.rb +5 -2
  25. data/lib/fluent/plugin/buffer.rb +194 -64
  26. data/lib/fluent/plugin/buffer/chunk.rb +28 -3
  27. data/lib/fluent/plugin/buffer/file_chunk.rb +5 -21
  28. data/lib/fluent/plugin/buffer/memory_chunk.rb +1 -11
  29. data/lib/fluent/plugin/exec_util.rb +2 -112
  30. data/lib/fluent/plugin/file_util.rb +3 -38
  31. data/lib/fluent/plugin/file_wrapper.rb +1 -1
  32. data/lib/fluent/plugin/filter_grep.rb +3 -7
  33. data/lib/fluent/plugin/filter_record_transformer.rb +5 -5
  34. data/lib/fluent/plugin/filter_stdout.rb +18 -11
  35. data/lib/fluent/plugin/formatter.rb +0 -48
  36. data/lib/fluent/plugin/formatter_csv.rb +7 -8
  37. data/lib/fluent/plugin/formatter_hash.rb +1 -4
  38. data/lib/fluent/plugin/formatter_json.rb +1 -4
  39. data/lib/fluent/plugin/formatter_ltsv.rb +5 -6
  40. data/lib/fluent/plugin/formatter_msgpack.rb +1 -4
  41. data/lib/fluent/plugin/formatter_out_file.rb +36 -3
  42. data/lib/fluent/plugin/formatter_stdout.rb +36 -1
  43. data/lib/fluent/plugin/in_dummy.rb +9 -2
  44. data/lib/fluent/plugin/in_exec.rb +20 -57
  45. data/lib/fluent/plugin/in_forward.rb +4 -3
  46. data/lib/fluent/plugin/in_object_space.rb +8 -44
  47. data/lib/fluent/plugin/in_syslog.rb +13 -24
  48. data/lib/fluent/plugin/in_tail.rb +3 -0
  49. data/lib/fluent/plugin/out_buffered_stdout.rb +14 -4
  50. data/lib/fluent/plugin/out_exec.rb +7 -5
  51. data/lib/fluent/plugin/out_exec_filter.rb +10 -10
  52. data/lib/fluent/plugin/out_file.rb +1 -3
  53. data/lib/fluent/plugin/out_forward.rb +38 -57
  54. data/lib/fluent/plugin/out_stdout.rb +14 -5
  55. data/lib/fluent/plugin/out_stream.rb +3 -0
  56. data/lib/fluent/plugin/output.rb +31 -14
  57. data/lib/fluent/plugin/parser.rb +0 -69
  58. data/lib/fluent/plugin/parser_apache.rb +10 -6
  59. data/lib/fluent/plugin/parser_apache_error.rb +8 -3
  60. data/lib/fluent/plugin/parser_csv.rb +3 -1
  61. data/lib/fluent/plugin/parser_json.rb +1 -1
  62. data/lib/fluent/plugin/parser_multiline.rb +5 -3
  63. data/lib/fluent/plugin/parser_nginx.rb +10 -6
  64. data/lib/fluent/plugin/parser_regexp.rb +73 -0
  65. data/lib/fluent/plugin/socket_util.rb +2 -148
  66. data/lib/fluent/plugin/storage_local.rb +1 -1
  67. data/lib/fluent/plugin/string_util.rb +3 -18
  68. data/lib/fluent/plugin_helper.rb +1 -0
  69. data/lib/fluent/plugin_helper/compat_parameters.rb +166 -41
  70. data/lib/fluent/plugin_helper/formatter.rb +30 -19
  71. data/lib/fluent/plugin_helper/inject.rb +25 -12
  72. data/lib/fluent/plugin_helper/parser.rb +22 -13
  73. data/lib/fluent/plugin_helper/storage.rb +22 -13
  74. data/lib/fluent/registry.rb +19 -6
  75. data/lib/fluent/supervisor.rb +27 -1
  76. data/lib/fluent/test/driver/base.rb +16 -92
  77. data/lib/fluent/test/driver/base_owned.rb +17 -53
  78. data/lib/fluent/test/driver/base_owner.rb +125 -0
  79. data/lib/fluent/test/driver/filter.rb +24 -2
  80. data/lib/fluent/test/driver/input.rb +2 -2
  81. data/lib/fluent/test/driver/multi_output.rb +2 -2
  82. data/lib/fluent/test/driver/output.rb +3 -5
  83. data/lib/fluent/test/helpers.rb +25 -0
  84. data/lib/fluent/test/input_test.rb +4 -4
  85. data/lib/fluent/test/output_test.rb +3 -3
  86. data/lib/fluent/version.rb +1 -1
  87. data/test/config/test_element.rb +135 -6
  88. data/test/plugin/test_buf_file.rb +71 -3
  89. data/test/plugin/test_buffer.rb +305 -86
  90. data/test/plugin/test_buffer_chunk.rb +60 -2
  91. data/test/plugin/test_buffer_file_chunk.rb +4 -3
  92. data/test/plugin/test_filter_grep.rb +25 -21
  93. data/test/plugin/test_filter_record_transformer.rb +75 -67
  94. data/test/plugin/test_filter_stdout.rb +171 -74
  95. data/test/plugin/test_formatter_csv.rb +94 -0
  96. data/test/plugin/test_formatter_json.rb +30 -0
  97. data/test/plugin/test_formatter_ltsv.rb +52 -0
  98. data/test/plugin/test_formatter_msgpack.rb +28 -0
  99. data/test/plugin/test_formatter_out_file.rb +95 -0
  100. data/test/plugin/test_formatter_single_value.rb +38 -0
  101. data/test/plugin/test_in_dummy.rb +95 -0
  102. data/test/plugin/test_in_exec.rb +27 -31
  103. data/test/plugin/test_in_forward.rb +24 -0
  104. data/test/plugin/test_in_gc_stat.rb +5 -5
  105. data/test/plugin/test_in_object_space.rb +4 -4
  106. data/test/plugin/test_in_syslog.rb +60 -35
  107. data/test/plugin/test_out_buffered_stdout.rb +17 -3
  108. data/test/plugin/test_out_forward.rb +93 -5
  109. data/test/plugin/test_out_stdout.rb +14 -3
  110. data/test/plugin/test_output_as_buffered_retries.rb +20 -0
  111. data/test/plugin/test_output_as_buffered_secondary.rb +16 -0
  112. data/test/plugin/test_output_as_standard.rb +22 -22
  113. data/test/plugin/test_parser_apache.rb +13 -9
  114. data/test/plugin/test_parser_apache_error.rb +11 -6
  115. data/test/plugin/test_parser_csv.rb +35 -25
  116. data/test/plugin/test_parser_nginx.rb +11 -5
  117. data/test/plugin/test_parser_regexp.rb +235 -68
  118. data/test/plugin/test_parser_tsv.rb +54 -58
  119. data/test/plugin_helper/test_compat_parameters.rb +111 -46
  120. data/test/plugin_helper/test_formatter.rb +40 -0
  121. data/test/plugin_helper/test_inject.rb +101 -2
  122. data/test/plugin_helper/test_parser.rb +40 -0
  123. data/test/plugin_helper/test_storage.rb +43 -0
  124. data/test/test_event.rb +93 -0
  125. data/test/test_event_router.rb +13 -4
  126. data/test/test_event_time.rb +0 -3
  127. data/test/test_formatter.rb +7 -164
  128. data/test/test_plugin_classes.rb +28 -1
  129. metadata +24 -3
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'fluent/test/driver/base'
17
+ require 'fluent/test/driver/base_owner'
18
18
  require 'fluent/test/driver/event_feeder'
19
19
 
20
20
  require 'fluent/plugin/filter'
@@ -22,12 +22,34 @@ require 'fluent/plugin/filter'
22
22
  module Fluent
23
23
  module Test
24
24
  module Driver
25
- class Filter < Base
25
+ class Filter < BaseOwner
26
26
  include EventFeeder
27
27
 
28
+ attr_reader :filtered
29
+
28
30
  def initialize(klass, opts: {}, &block)
29
31
  super
30
32
  raise ArgumentError, "plugin is not an instance of Fluent::Plugin::Filter" unless @instance.is_a? Fluent::Plugin::Filter
33
+ @filtered = []
34
+ end
35
+
36
+ def filtered_records
37
+ @filtered.map {|_time, record| record }
38
+ end
39
+
40
+ def instance_hook_after_started
41
+ super
42
+ filter_hook = ->(time, record) { @filtered << [time, record] }
43
+ m = Module.new do
44
+ define_method(:filter_stream) do |tag, es|
45
+ new_es = super(tag, es)
46
+ new_es.each do |time, record|
47
+ filter_hook.call(time, record)
48
+ end
49
+ new_es
50
+ end
51
+ end
52
+ @instance.singleton_class.prepend(m)
31
53
  end
32
54
  end
33
55
  end
@@ -14,13 +14,13 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'fluent/test/driver/base'
17
+ require 'fluent/test/driver/base_owner'
18
18
  require 'fluent/plugin/input'
19
19
 
20
20
  module Fluent
21
21
  module Test
22
22
  module Driver
23
- class Input < Base
23
+ class Input < BaseOwner
24
24
  def initialize(klass, opts: {}, &block)
25
25
  super
26
26
  raise ArgumentError, "plugin is not an instance of Fluent::Plugin::Input" unless @instance.is_a? Fluent::Plugin::Input
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'fluent/test/driver/base'
17
+ require 'fluent/test/driver/base_owner'
18
18
  require 'fluent/test/driver/event_feeder'
19
19
 
20
20
  require 'fluent/plugin/multi_output'
@@ -22,7 +22,7 @@ require 'fluent/plugin/multi_output'
22
22
  module Fluent
23
23
  module Test
24
24
  module Driver
25
- class MultiOutput < Base
25
+ class MultiOutput < BaseOwner
26
26
  include EventFeeder
27
27
 
28
28
  def initialize(klass, opts: {}, &block)
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'fluent/test/driver/base'
17
+ require 'fluent/test/driver/base_owner'
18
18
  require 'fluent/test/driver/event_feeder'
19
19
 
20
20
  require 'fluent/plugin/output'
@@ -22,7 +22,7 @@ require 'fluent/plugin/output'
22
22
  module Fluent
23
23
  module Test
24
24
  module Driver
25
- class Output < Base
25
+ class Output < BaseOwner
26
26
  include EventFeeder
27
27
 
28
28
  def initialize(klass, opts: {}, &block)
@@ -67,9 +67,7 @@ module Fluent
67
67
  result
68
68
  end
69
69
  end
70
- @instance.singleton_class.module_eval do
71
- prepend m
72
- end
70
+ @instance.singleton_class.prepend m
73
71
  end
74
72
  end
75
73
  end
@@ -37,6 +37,22 @@ module Fluent
37
37
  end
38
38
  end
39
39
 
40
+ def time2str(time, localtime: false, format: nil)
41
+ if format
42
+ if localtime
43
+ Time.at(time).strftime(format)
44
+ else
45
+ Time.at(time).utc.strftime(format)
46
+ end
47
+ else
48
+ if localtime
49
+ Time.at(time).iso8601
50
+ else
51
+ Time.at(time).utc.iso8601
52
+ end
53
+ end
54
+ end
55
+
40
56
  def msgpack(type)
41
57
  case type
42
58
  when :factory
@@ -49,6 +65,15 @@ module Fluent
49
65
  raise ArgumentError, "unknown msgpack object type '#{type}'"
50
66
  end
51
67
  end
68
+
69
+ def capture_log(driver)
70
+ tmp = driver.instance.log.out
71
+ driver.instance.log.out = StringIO.new
72
+ yield
73
+ return driver.instance.log.out.string
74
+ ensure
75
+ driver.instance.log.out = tmp
76
+ end
52
77
  end
53
78
  end
54
79
  end
@@ -110,12 +110,12 @@ module Fluent
110
110
 
111
111
  def run(num_waits = 10, &block)
112
112
  m = method(:emit_stream)
113
- (class << Engine; self; end).module_eval do
114
- prepend EmitStreamWrapper
113
+ unless Engine.singleton_class.ancestors.include?(EmitStreamWrapper)
114
+ Engine.singleton_class.prepend EmitStreamWrapper
115
115
  end
116
116
  Engine.emit_stream_callee = m
117
- (class << instance.router; self; end).module_eval do
118
- prepend EmitStreamWrapper
117
+ unless instance.router.singleton_class.ancestors.include?(EmitStreamWrapper)
118
+ instance.router.singleton_class.prepend EmitStreamWrapper
119
119
  end
120
120
  instance.router.emit_stream_callee = m
121
121
 
@@ -84,9 +84,9 @@ module Fluent
84
84
  end
85
85
 
86
86
  chunk = if @instance.instance_eval{ @chunk_key_tag }
87
- @instance.buffer.generate_chunk(@instance.metadata(@tag, nil, nil))
87
+ @instance.buffer.generate_chunk(@instance.metadata(@tag, nil, nil)).staged!
88
88
  else
89
- @instance.buffer.generate_chunk(@instance.metadata(nil, nil, nil))
89
+ @instance.buffer.generate_chunk(@instance.metadata(nil, nil, nil)).staged!
90
90
  end
91
91
  chunk.concat(buffer, es.size)
92
92
 
@@ -140,7 +140,7 @@ module Fluent
140
140
  end
141
141
 
142
142
  lines.keys.each do |meta|
143
- chunk = @instance.buffer.generate_chunk(meta)
143
+ chunk = @instance.buffer.generate_chunk(meta).staged!
144
144
  chunk.append(lines[meta])
145
145
  begin
146
146
  result.push(@instance.write(chunk))
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '0.14.1'
19
+ VERSION = '0.14.2'
20
20
 
21
21
  end
@@ -1,17 +1,13 @@
1
1
  require_relative '../helper'
2
2
  require 'fluent/config/element'
3
+ require 'fluent/config/configure_proxy'
4
+ require 'fluent/configurable'
3
5
 
4
6
  class TestConfigElement < ::Test::Unit::TestCase
5
7
  def element(name = 'ROOT', arg = '', attrs = {}, elements = [], unused = nil)
6
8
  Fluent::Config::Element.new(name, arg, attrs, elements, unused)
7
9
  end
8
10
 
9
- sub_test_case 'Most test' do
10
- test 'should be written' do
11
- pend 'TODO'
12
- end
13
- end
14
-
15
11
  sub_test_case '#elements=' do
16
12
  test 'elements can be set by others' do
17
13
  e = element()
@@ -271,4 +267,137 @@ CONF
271
267
  assert_equal(dump.chomp, e.inspect)
272
268
  end
273
269
  end
270
+
271
+ sub_test_case 'for sections which has secret parameter' do
272
+ setup do
273
+ @type_lookup = ->(type){ Fluent::Configurable.lookup_type(type) }
274
+ p1 = Fluent::Config::ConfigureProxy.new(:match, type_lookup: @type_lookup)
275
+ p1.config_param :str1, :string
276
+ p1.config_param :str2, :string, secret: true
277
+ p1.config_param :enum1, :enum, list: [:a, :b, :c]
278
+ p1.config_param :enum2, :enum, list: [:a, :b, :c], secret: true
279
+ p1.config_param :bool1, :bool
280
+ p1.config_param :bool2, :bool, secret: true
281
+ p1.config_param :int1, :integer
282
+ p1.config_param :int2, :integer, secret: true
283
+ p1.config_param :float1, :float
284
+ p1.config_param :float2, :float, secret: true
285
+ p2 = Fluent::Config::ConfigureProxy.new(:match, type_lookup: @type_lookup)
286
+ p2.config_param :size1, :size
287
+ p2.config_param :size2, :size, secret: true
288
+ p2.config_param :time1, :time
289
+ p2.config_param :time2, :time, secret: true
290
+ p2.config_param :array1, :array
291
+ p2.config_param :array2, :array, secret: true
292
+ p2.config_param :hash1, :hash
293
+ p2.config_param :hash2, :hash, secret: true
294
+ p1.config_section :mysection do
295
+ config_param :str1, :string
296
+ config_param :str2, :string, secret: true
297
+ config_param :enum1, :enum, list: [:a, :b, :c]
298
+ config_param :enum2, :enum, list: [:a, :b, :c], secret: true
299
+ config_param :bool1, :bool
300
+ config_param :bool2, :bool, secret: true
301
+ config_param :int1, :integer
302
+ config_param :int2, :integer, secret: true
303
+ config_param :float1, :float
304
+ config_param :float2, :float, secret: true
305
+ config_param :size1, :size
306
+ config_param :size2, :size, secret: true
307
+ config_param :time1, :time
308
+ config_param :time2, :time, secret: true
309
+ config_param :array1, :array
310
+ config_param :array2, :array, secret: true
311
+ config_param :hash1, :hash
312
+ config_param :hash2, :hash, secret: true
313
+ end
314
+ params = {
315
+ 'str1' => 'aaa', 'str2' => 'bbb', 'enum1' => 'a', 'enum2' => 'b', 'bool1' => 'true', 'bool2' => 'yes',
316
+ 'int1' => '1', 'int2' => '2', 'float1' => '1.0', 'float2' => '0.5', 'size1' => '1k', 'size2' => '1m',
317
+ 'time1' => '5m', 'time2' => '3h', 'array1' => 'a,b,c', 'array2' => 'd,e,f',
318
+ 'hash1' => 'a:1,b:2', 'hash2' => 'a:2,b:4',
319
+ 'unknown1' => 'yay', 'unknown2' => 'boo',
320
+ }
321
+ e2 = Fluent::Config::Element.new('mysection', '', params.dup, [])
322
+ e2.corresponding_proxies << p1.sections.values.first
323
+ @e = Fluent::Config::Element.new('match', '**', params, [e2])
324
+ @e.corresponding_proxies << p1
325
+ @e.corresponding_proxies << p2
326
+ end
327
+
328
+ sub_test_case '#to_masked_element' do
329
+ test 'returns a new element object which has masked values for secret parameters and elements' do
330
+ e = @e.to_masked_element
331
+ assert_equal 'aaa', e['str1']
332
+ assert_equal 'xxxxxx', e['str2']
333
+ assert_equal 'a', e['enum1']
334
+ assert_equal 'xxxxxx', e['enum2']
335
+ assert_equal 'true', e['bool1']
336
+ assert_equal 'xxxxxx', e['bool2']
337
+ assert_equal '1', e['int1']
338
+ assert_equal 'xxxxxx', e['int2']
339
+ assert_equal '1.0', e['float1']
340
+ assert_equal 'xxxxxx', e['float2']
341
+ assert_equal '1k', e['size1']
342
+ assert_equal 'xxxxxx', e['size2']
343
+ assert_equal '5m', e['time1']
344
+ assert_equal 'xxxxxx', e['time2']
345
+ assert_equal 'a,b,c', e['array1']
346
+ assert_equal 'xxxxxx', e['array2']
347
+ assert_equal 'a:1,b:2', e['hash1']
348
+ assert_equal 'xxxxxx', e['hash2']
349
+ assert_equal 'yay', e['unknown1']
350
+ assert_equal 'boo', e['unknown2']
351
+ e2 = e.elements.first
352
+ assert_equal 'aaa', e2['str1']
353
+ assert_equal 'xxxxxx', e2['str2']
354
+ assert_equal 'a', e2['enum1']
355
+ assert_equal 'xxxxxx', e2['enum2']
356
+ assert_equal 'true', e2['bool1']
357
+ assert_equal 'xxxxxx', e2['bool2']
358
+ assert_equal '1', e2['int1']
359
+ assert_equal 'xxxxxx', e2['int2']
360
+ assert_equal '1.0', e2['float1']
361
+ assert_equal 'xxxxxx', e2['float2']
362
+ assert_equal '1k', e2['size1']
363
+ assert_equal 'xxxxxx', e2['size2']
364
+ assert_equal '5m', e2['time1']
365
+ assert_equal 'xxxxxx', e2['time2']
366
+ assert_equal 'a,b,c', e2['array1']
367
+ assert_equal 'xxxxxx', e2['array2']
368
+ assert_equal 'a:1,b:2', e2['hash1']
369
+ assert_equal 'xxxxxx', e2['hash2']
370
+ assert_equal 'yay', e2['unknown1']
371
+ assert_equal 'boo', e2['unknown2']
372
+ end
373
+ end
374
+
375
+ sub_test_case '#secret_param?' do
376
+ test 'returns boolean which shows values of given key will be masked' do
377
+ assert !@e.secret_param?('str1')
378
+ assert @e.secret_param?('str2')
379
+ assert !@e.elements.first.secret_param?('str1')
380
+ assert @e.elements.first.secret_param?('str2')
381
+ end
382
+ end
383
+
384
+ sub_test_case '#param_type' do
385
+ test 'returns parameter type which are registered in corresponding proxy' do
386
+ assert_equal :string, @e.param_type('str1')
387
+ assert_equal :string, @e.param_type('str2')
388
+ assert_equal :enum, @e.param_type('enum1')
389
+ assert_equal :enum, @e.param_type('enum2')
390
+ assert_nil @e.param_type('unknown1')
391
+ assert_nil @e.param_type('unknown2')
392
+ end
393
+ end
394
+
395
+ # sub_test_case '#dump_value'
396
+ sub_test_case '#dump_value' do
397
+ test 'dumps parameter_name and values with leading indentation' do
398
+ assert_equal "str1 aaa\n", @e.dump_value("str1", @e["str1"], "")
399
+ assert_equal "str2 xxxxxx\n", @e.dump_value("str2", @e["str2"], "")
400
+ end
401
+ end
402
+ end
274
403
  end
@@ -181,7 +181,7 @@ class FileBufferTest < Test::Unit::TestCase
181
181
  assert c1.is_a? Fluent::Plugin::Buffer::FileChunk
182
182
  assert_equal m1, c1.metadata
183
183
  assert c1.empty?
184
- assert_equal :staged, c1.state
184
+ assert_equal :unstaged, c1.state
185
185
  assert_equal Fluent::Plugin::Buffer::FileChunk::FILE_PERMISSION, c1.permission
186
186
  assert_equal @bufpath.gsub('.*.', ".b#{Fluent::UniqueId.hex(c1.unique_id)}."), c1.path
187
187
  assert{ File.stat(c1.path).mode.to_s(8).end_with?('644') }
@@ -191,7 +191,7 @@ class FileBufferTest < Test::Unit::TestCase
191
191
  assert c2.is_a? Fluent::Plugin::Buffer::FileChunk
192
192
  assert_equal m2, c2.metadata
193
193
  assert c2.empty?
194
- assert_equal :staged, c2.state
194
+ assert_equal :unstaged, c2.state
195
195
  assert_equal Fluent::Plugin::Buffer::FileChunk::FILE_PERMISSION, c2.permission
196
196
  assert_equal @bufpath.gsub('.*.', ".b#{Fluent::UniqueId.hex(c2.unique_id)}."), c2.path
197
197
  assert{ File.stat(c2.path).mode.to_s(8).end_with?('644') }
@@ -221,7 +221,7 @@ class FileBufferTest < Test::Unit::TestCase
221
221
  assert c.is_a? Fluent::Plugin::Buffer::FileChunk
222
222
  assert_equal m, c.metadata
223
223
  assert c.empty?
224
- assert_equal :staged, c.state
224
+ assert_equal :unstaged, c.state
225
225
  assert_equal 0600, c.permission
226
226
  assert_equal bufpath.gsub('.*.', ".b#{Fluent::UniqueId.hex(c.unique_id)}."), c.path
227
227
  assert{ File.stat(c.path).mode.to_s(8).end_with?('600') }
@@ -500,4 +500,72 @@ class FileBufferTest < Test::Unit::TestCase
500
500
  assert_equal Time.parse('2016-04-17 14:01:22 -0700'), queue[3].modified_at
501
501
  end
502
502
  end
503
+
504
+ sub_test_case 'there are some non-buffer chunk files, with a path without buffer chunk ids' do
505
+ setup do
506
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
507
+
508
+ @c1id = Fluent::UniqueId.generate
509
+ p1 = File.join(@bufdir, "etest.201604171358.q#{Fluent::UniqueId.hex(@c1id)}.log")
510
+ File.open(p1, 'wb') do |f|
511
+ f.write ["t1.test", event_time('2016-04-17 13:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
512
+ f.write ["t2.test", event_time('2016-04-17 13:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
513
+ f.write ["t3.test", event_time('2016-04-17 13:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
514
+ f.write ["t4.test", event_time('2016-04-17 13:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
515
+ end
516
+ FileUtils.touch(p1, mtime: Time.parse('2016-04-17 13:58:28 -0700'))
517
+
518
+ @not_chunk = File.join(@bufdir, 'etest.20160416.log')
519
+ File.open(@not_chunk, 'wb') do |f|
520
+ f.write ["t1.test", event_time('2016-04-16 23:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
521
+ f.write ["t2.test", event_time('2016-04-16 23:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
522
+ f.write ["t3.test", event_time('2016-04-16 23:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
523
+ f.write ["t4.test", event_time('2016-04-16 23:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
524
+ end
525
+ FileUtils.touch(@not_chunk, mtime: Time.parse('2016-04-17 00:00:00 -0700'))
526
+
527
+ @bufpath = File.join(@bufdir, 'etest.*.log')
528
+
529
+ Fluent::Test.setup
530
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
531
+ @p = Fluent::Plugin::FileBuffer.new
532
+ @p.owner = @d
533
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
534
+ @p.start
535
+ end
536
+
537
+ teardown do
538
+ if @p
539
+ @p.stop unless @p.stopped?
540
+ @p.before_shutdown unless @p.before_shutdown?
541
+ @p.shutdown unless @p.shutdown?
542
+ @p.after_shutdown unless @p.after_shutdown?
543
+ @p.close unless @p.closed?
544
+ @p.terminate unless @p.terminated?
545
+ end
546
+ if @bufdir
547
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
548
+ next if ['.', '..'].include?(File.basename(path))
549
+ File.delete(path)
550
+ end
551
+ end
552
+ end
553
+
554
+ test '#resume returns queued chunks for files without metadata, while ignoring non-chunk looking files' do
555
+ assert_equal 0, @p.stage.size
556
+ assert_equal 1, @p.queue.size
557
+
558
+ queue = @p.queue
559
+
560
+ m = metadata()
561
+
562
+ assert_equal @c1id, queue[0].unique_id
563
+ assert_equal m, queue[0].metadata
564
+ assert_equal 0, queue[0].size
565
+ assert_equal :queued, queue[0].state
566
+ assert_equal Time.parse('2016-04-17 13:58:28 -0700'), queue[0].modified_at
567
+
568
+ assert File.exist?(@not_chunk)
569
+ end
570
+ end
503
571
  end