fluentd 0.14.0 → 0.14.1

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.

Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/example/copy_roundrobin.conf +39 -0
  3. data/example/filter_stdout.conf +5 -5
  4. data/example/in_forward.conf +2 -2
  5. data/example/in_http.conf +2 -2
  6. data/example/in_syslog.conf +2 -2
  7. data/example/in_tail.conf +2 -2
  8. data/example/in_tcp.conf +2 -2
  9. data/example/in_udp.conf +2 -2
  10. data/example/out_buffered_null.conf +32 -0
  11. data/example/out_copy.conf +4 -4
  12. data/example/out_file.conf +2 -2
  13. data/example/out_forward.conf +2 -2
  14. data/example/v0_12_filter.conf +8 -8
  15. data/fluentd.gemspec +1 -1
  16. data/lib/fluent/command/fluentd.rb +6 -1
  17. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  18. data/lib/fluent/compat/input.rb +1 -0
  19. data/lib/fluent/compat/output.rb +1 -0
  20. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  21. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  22. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  23. data/lib/fluent/compat/type_converter.rb +90 -0
  24. data/lib/fluent/config/configure_proxy.rb +24 -4
  25. data/lib/fluent/config/dsl.rb +18 -1
  26. data/lib/fluent/config/v1_parser.rb +3 -2
  27. data/lib/fluent/configurable.rb +1 -1
  28. data/lib/fluent/event.rb +37 -9
  29. data/lib/fluent/mixin.rb +12 -286
  30. data/lib/fluent/plugin/buffer.rb +2 -2
  31. data/lib/fluent/plugin/in_dummy.rb +5 -1
  32. data/lib/fluent/plugin/in_gc_stat.rb +7 -37
  33. data/lib/fluent/plugin/in_http.rb +2 -0
  34. data/lib/fluent/plugin/{in_stream.rb → in_unix.rb} +0 -0
  35. data/lib/fluent/plugin/out_buffered_stdout.rb +60 -0
  36. data/lib/fluent/plugin/out_copy.rb +8 -51
  37. data/lib/fluent/plugin/out_null.rb +5 -5
  38. data/lib/fluent/plugin/out_relabel.rb +5 -5
  39. data/lib/fluent/plugin/out_roundrobin.rb +13 -40
  40. data/lib/fluent/plugin/output.rb +9 -0
  41. data/lib/fluent/plugin_helper.rb +2 -0
  42. data/lib/fluent/plugin_helper/formatter.rb +138 -0
  43. data/lib/fluent/plugin_helper/inject.rb +112 -0
  44. data/lib/fluent/plugin_helper/parser.rb +138 -0
  45. data/lib/fluent/plugin_helper/storage.rb +64 -50
  46. data/lib/fluent/process.rb +6 -1
  47. data/lib/fluent/registry.rb +1 -1
  48. data/lib/fluent/supervisor.rb +20 -2
  49. data/lib/fluent/test.rb +30 -5
  50. data/lib/fluent/test/base.rb +2 -66
  51. data/lib/fluent/test/driver/base.rb +3 -0
  52. data/lib/fluent/test/driver/base_owned.rb +106 -0
  53. data/lib/fluent/test/driver/formatter.rb +30 -0
  54. data/lib/fluent/test/driver/multi_output.rb +52 -0
  55. data/lib/fluent/test/driver/owner.rb +32 -0
  56. data/lib/fluent/test/driver/parser.rb +30 -0
  57. data/lib/fluent/test/helpers.rb +54 -0
  58. data/lib/fluent/test/log.rb +73 -0
  59. data/lib/fluent/time.rb +71 -0
  60. data/lib/fluent/version.rb +1 -1
  61. data/test/compat/test_parser.rb +82 -0
  62. data/test/config/test_configure_proxy.rb +15 -0
  63. data/test/config/test_dsl.rb +180 -2
  64. data/test/helper.rb +2 -24
  65. data/test/plugin/test_in_gc_stat.rb +6 -6
  66. data/test/plugin/test_in_http.rb +49 -32
  67. data/test/plugin/{test_in_stream.rb → test_in_unix.rb} +1 -1
  68. data/test/plugin/test_out_buffered_stdout.rb +108 -0
  69. data/test/plugin/test_out_copy.rb +88 -127
  70. data/test/plugin/test_out_null.rb +29 -0
  71. data/test/plugin/test_out_relabel.rb +28 -0
  72. data/test/plugin/test_out_roundrobin.rb +35 -29
  73. data/test/plugin/test_out_stdout.rb +4 -4
  74. data/test/plugin/test_output_as_buffered.rb +51 -0
  75. data/test/plugin/test_output_as_buffered_secondary.rb +13 -0
  76. data/test/plugin/test_parser_apache.rb +38 -0
  77. data/test/plugin/test_parser_apache2.rb +38 -0
  78. data/test/plugin/test_parser_apache_error.rb +40 -0
  79. data/test/plugin/test_parser_base.rb +32 -0
  80. data/test/plugin/test_parser_csv.rb +94 -0
  81. data/test/plugin/test_parser_json.rb +107 -0
  82. data/test/plugin/test_parser_labeled_tsv.rb +129 -0
  83. data/test/plugin/test_parser_multiline.rb +100 -0
  84. data/test/plugin/test_parser_nginx.rb +42 -0
  85. data/test/plugin/test_parser_none.rb +53 -0
  86. data/test/plugin/test_parser_regexp.rb +110 -0
  87. data/test/plugin/test_parser_syslog.rb +66 -0
  88. data/test/plugin/test_parser_time.rb +46 -0
  89. data/test/plugin/test_parser_tsv.rb +125 -0
  90. data/test/plugin_helper/test_child_process.rb +11 -2
  91. data/test/plugin_helper/test_formatter.rb +212 -0
  92. data/test/plugin_helper/test_inject.rb +388 -0
  93. data/test/plugin_helper/test_parser.rb +223 -0
  94. data/test/plugin_helper/test_retry_state.rb +40 -40
  95. data/test/plugin_helper/test_storage.rb +77 -10
  96. data/test/scripts/fluent/plugin/out_test.rb +22 -17
  97. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  98. data/test/test_event.rb +57 -0
  99. data/test/test_formatter.rb +0 -178
  100. data/test/test_output.rb +2 -152
  101. data/test/test_root_agent.rb +3 -2
  102. data/test/test_supervisor.rb +93 -26
  103. data/test/test_time_formatter.rb +186 -0
  104. metadata +69 -7
  105. data/test/test_parser.rb +0 -1087
@@ -42,6 +42,7 @@ require 'fileutils'
42
42
  require 'fluent/config/element'
43
43
  require 'fluent/log'
44
44
  require 'fluent/test'
45
+ require 'fluent/test/helpers'
45
46
  require 'fluent/plugin/base'
46
47
  require 'fluent/log'
47
48
  require 'fluent/plugin_id'
@@ -67,30 +68,7 @@ unless defined?(Test::Unit::AssertionFailedError)
67
68
  end
68
69
  end
69
70
 
70
- def config_element(name = 'test', argument = '', params = {}, elements = [])
71
- Fluent::Config::Element.new(name, argument, params, elements)
72
- end
73
-
74
- def event_time(str=nil)
75
- if str
76
- Fluent::EventTime.parse(str)
77
- else
78
- Fluent::EventTime.now
79
- end
80
- end
81
-
82
- def msgpack(type)
83
- case type
84
- when :factory
85
- Fluent::MessagePackFactory.factory
86
- when :packer
87
- Fluent::MessagePackFactory.packer
88
- when :unpacker
89
- Fluent::MessagePackFactory.unpacker
90
- else
91
- raise ArgumentError, "unknown msgpack object type '#{type}'"
92
- end
93
- end
71
+ include Fluent::Test::Helpers
94
72
 
95
73
  def unused_port(num = 1)
96
74
  ports = []
@@ -1,5 +1,5 @@
1
1
  require_relative '../helper'
2
- require 'fluent/test'
2
+ require 'fluent/test/driver/input'
3
3
  require 'fluent/plugin/in_gc_stat'
4
4
 
5
5
  class GCStatInputTest < Test::Unit::TestCase
@@ -13,7 +13,7 @@ class GCStatInputTest < Test::Unit::TestCase
13
13
  ]
14
14
 
15
15
  def create_driver(conf=CONFIG)
16
- Fluent::Test::InputTestDriver.new(Fluent::GCStatInput).configure(conf)
16
+ Fluent::Test::Driver::Input.new(Fluent::Plugin::GCStatInput).configure(conf)
17
17
  end
18
18
 
19
19
  def test_configure
@@ -31,9 +31,9 @@ class GCStatInputTest < Test::Unit::TestCase
31
31
  sleep 2
32
32
  end
33
33
 
34
- emits = d.emits
35
- assert(emits.length > 0)
36
- assert_equal(stat, emits[0][2])
37
- assert(emits[0][1].is_a?(Fluent::EventTime))
34
+ events = d.events
35
+ assert(events.length > 0)
36
+ assert_equal(stat, events[0][2])
37
+ assert(events[0][1].is_a?(Fluent::EventTime))
38
38
  end
39
39
  end
@@ -147,6 +147,39 @@ class HttpInputTest < Test::Unit::TestCase
147
147
 
148
148
  end
149
149
 
150
+ def test_json_with_add_remote_addr_given_x_forwarded_for
151
+ d = create_driver(CONFIG + "add_remote_addr true")
152
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
153
+
154
+ d.expect_emit "tag1", time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>1}
155
+ d.expect_emit "tag2", time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>1}
156
+
157
+ d.run do
158
+ d.expected_emits.each {|tag,_time,record|
159
+ res = post("/#{tag}", {"json"=>record.to_json, "time"=>_time.to_s}, {"X-Forwarded-For"=>"129.78.138.66, 127.0.0.1"})
160
+ assert_equal "200", res.code
161
+ }
162
+ end
163
+
164
+ end
165
+
166
+ def test_multi_json_with_add_remote_addr_given_x_forwarded_for
167
+ d = create_driver(CONFIG + "add_remote_addr true")
168
+
169
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
170
+ events = [{"a"=>1},{"a"=>2}]
171
+ tag = "tag1"
172
+
173
+ d.expect_emit "tag1", time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>1}
174
+ d.expect_emit "tag1", time, {"REMOTE_ADDR"=>"129.78.138.66", "a"=>2}
175
+
176
+ d.run do
177
+ res = post("/#{tag}", {"json"=>events.to_json, "time"=>time.to_s}, {"X-Forwarded-For"=>"129.78.138.66, 127.0.0.1"})
178
+ assert_equal "200", res.code
179
+ end
180
+
181
+ end
182
+
150
183
  def test_multi_json_with_add_http_headers
151
184
  d = create_driver(CONFIG + "add_http_headers true")
152
185
 
@@ -302,50 +335,34 @@ class HttpInputTest < Test::Unit::TestCase
302
335
  d = create_driver(CONFIG + "cors_allow_origins [\"http://foo.com\"]")
303
336
  assert_equal ["http://foo.com"], d.instance.cors_allow_origins
304
337
 
305
- test_in_http_cros_allowed = nil
306
- acao = nil
338
+ time = Fluent::EventTime.new(Time.parse("2011-01-02 13:14:15 UTC").to_i)
307
339
 
308
- begin
309
- d.run do
310
- Net::HTTP.start("127.0.0.1", PORT) do |http|
311
- req = Net::HTTP::Post.new("/foo/bar", {"Origin" => "http://foo.com", "Content-Type" => "application/octet-stream"})
312
- res = http.request(req)
340
+ d.expect_emit "tag1", time, {"a"=>1}
341
+ d.expect_emit "tag2", time, {"a"=>1}
313
342
 
314
- acao = res["Access-Control-Allow-Origin"]
315
- end
316
- end
317
- test_in_http_cros_allowed = true
318
- rescue
319
- test_in_http_cros_allowed = false
343
+ d.run do
344
+ d.expected_emits.each {|tag,_time,record|
345
+ res = post("/#{tag}", {"json"=>record.to_json, "time"=>_time.to_s}, {"Origin"=>"http://foo.com"})
346
+ assert_equal "200", res.code
347
+ assert_equal "http://foo.com", res["Access-Control-Allow-Origin"]
348
+ }
320
349
  end
321
-
322
- assert_equal true, test_in_http_cros_allowed
323
- assert_equal "http://foo.com", acao
324
350
  end
325
351
 
326
352
  def test_cors_disallowed
327
353
  d = create_driver(CONFIG + "cors_allow_origins [\"http://foo.com\"]")
328
354
  assert_equal ["http://foo.com"], d.instance.cors_allow_origins
329
355
 
330
- test_in_http_cros_disallowed = nil
331
- response_code = nil
356
+ time = Fluent::EventTime.new(Time.parse("2011-01-02 13:14:15 UTC").to_i)
332
357
 
333
- begin
334
- d.run do
335
- Net::HTTP.start("127.0.0.1", PORT) do |http|
336
- req = Net::HTTP::Post.new("/foo/bar", {"Origin" => "http://bar.com", "Content-Type" => "application/octet-stream"})
337
- res = http.request(req)
358
+ d.expected_emits_length = 0
359
+ d.run do
360
+ res = post("/tag1", {"json"=>{"a"=>1}.to_json, "time"=>time.to_s}, {"Origin"=>"http://bar.com"})
361
+ assert_equal "403", res.code
338
362
 
339
- response_code = res.code
340
- end
341
- end
342
- test_in_http_cros_disallowed = true
343
- rescue
344
- test_in_http_cros_disallowed = false
363
+ res = post("/tag2", {"json"=>{"a"=>1}.to_json, "time"=>time.to_s}, {"Origin"=>"http://bar.com"})
364
+ assert_equal "403", res.code
345
365
  end
346
-
347
- assert_equal true, test_in_http_cros_disallowed
348
- assert_equal "403", response_code
349
366
  end
350
367
 
351
368
  $test_in_http_connection_object_ids = []
@@ -1,6 +1,6 @@
1
1
  require_relative '../helper'
2
2
  require 'fluent/test'
3
- require 'fluent/plugin/in_stream'
3
+ require 'fluent/plugin/in_unix'
4
4
 
5
5
  module StreamInputTest
6
6
  def setup
@@ -0,0 +1,108 @@
1
+ require_relative '../helper'
2
+ require 'fluent/test/driver/output'
3
+ require 'fluent/plugin/out_buffered_stdout'
4
+
5
+ class BufferedStdoutOutputTest < Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ CONFIG = %[
11
+ ]
12
+
13
+ def create_driver(conf = CONFIG)
14
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::BufferedStdoutOutput).configure(conf)
15
+ end
16
+
17
+ test 'default configure' do
18
+ d = create_driver
19
+ assert_equal 'json', d.instance.output_type
20
+ assert_equal 10 * 1024, d.instance.buffer_config.chunk_limit_size
21
+ assert d.instance.buffer_config.flush_at_shutdown
22
+ assert_equal ['tag'], d.instance.buffer_config.chunk_keys
23
+ assert d.instance.chunk_key_tag
24
+ assert !d.instance.chunk_key_time
25
+ assert_equal [], d.instance.chunk_keys
26
+ end
27
+
28
+ test 'configure with output_type' do
29
+ d = create_driver(CONFIG + "\noutput_type json")
30
+ assert_equal 'json', d.instance.output_type
31
+
32
+ d = create_driver(CONFIG + "\noutput_type hash")
33
+ assert_equal 'hash', d.instance.output_type
34
+
35
+ assert_raise(Fluent::ConfigError) do
36
+ d = create_driver(CONFIG + "\noutput_type foo")
37
+ end
38
+ end
39
+
40
+ sub_test_case "emit json" do
41
+ data('oj' => 'oj', 'yajl' => 'yajl')
42
+ test '#write(synchronous)' do |data|
43
+ d = create_driver(CONFIG + "\noutput_type json\njson_parser #{data}")
44
+ time = event_time()
45
+
46
+ out = capture_log do
47
+ d.run(default_tag: 'test', flush: true) do
48
+ d.feed(time, {'test' => 'test'})
49
+ end
50
+ end
51
+ assert_equal "#{Time.at(time).localtime} test: {\"test\":\"test\"}\n", out
52
+ end
53
+
54
+ data('oj' => 'oj', 'yajl' => 'yajl')
55
+ test '#try_write(asynchronous)' do |data|
56
+ d = create_driver(CONFIG + "\noutput_type json\njson_parser #{data}")
57
+ time = event_time()
58
+ d.instance.delayed = true
59
+
60
+ out = capture_log do
61
+ d.run(default_tag: 'test', flush: true, shutdown: false) do
62
+ d.feed(time, {'test' => 'test'})
63
+ end
64
+ end
65
+
66
+ assert_equal "#{Time.at(time).localtime} test: {\"test\":\"test\"}\n", out
67
+ end
68
+ end
69
+
70
+ sub_test_case 'emit hash' do
71
+ test '#write(synchronous)' do
72
+ d = create_driver(CONFIG + "\noutput_type hash")
73
+ time = event_time()
74
+
75
+ out = capture_log do
76
+ d.run(default_tag: 'test', flush: true) do
77
+ d.feed(time, {'test' => 'test'})
78
+ end
79
+ end
80
+
81
+ assert_equal "#{Time.at(time).localtime} test: {\"test\"=>\"test\"}\n", out
82
+ end
83
+
84
+ test '#try_write(asynchronous)' do
85
+ d = create_driver(CONFIG + "\noutput_type hash")
86
+ time = event_time()
87
+ d.instance.delayed = true
88
+
89
+ out = capture_log do
90
+ d.run(default_tag: 'test', flush: true, shutdown: false) do
91
+ d.feed(time, {'test' => 'test'})
92
+ end
93
+ end
94
+
95
+ assert_equal "#{Time.at(time).localtime} test: {\"test\"=>\"test\"}\n", out
96
+ end
97
+ end
98
+
99
+ # Capture the log output of the block given
100
+ def capture_log(&block)
101
+ tmp = $log
102
+ $log = StringIO.new
103
+ yield
104
+ return $log.string
105
+ ensure
106
+ $log = tmp
107
+ end
108
+ end
@@ -1,12 +1,14 @@
1
1
  require_relative '../helper'
2
- require 'fluent/test'
2
+ require 'fluent/test/driver/multi_output'
3
3
  require 'fluent/plugin/out_copy'
4
+ require 'fluent/event'
4
5
 
5
6
  class CopyOutputTest < Test::Unit::TestCase
6
7
  class << self
7
8
  def startup
8
9
  $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'scripts'))
9
10
  require 'fluent/plugin/out_test'
11
+ require 'fluent/plugin/out_test2'
10
12
  end
11
13
 
12
14
  def shutdown
@@ -20,21 +22,21 @@ class CopyOutputTest < Test::Unit::TestCase
20
22
 
21
23
  CONFIG = %[
22
24
  <store>
23
- type test
25
+ @type test
24
26
  name c0
25
27
  </store>
26
28
  <store>
27
- type test
29
+ @type test2
28
30
  name c1
29
31
  </store>
30
32
  <store>
31
- type test
33
+ @type test
32
34
  name c2
33
35
  </store>
34
36
  ]
35
37
 
36
38
  def create_driver(conf = CONFIG)
37
- Fluent::Test::OutputTestDriver.new(Fluent::CopyOutput).configure(conf)
39
+ Fluent::Test::Driver::MultiOutput.new(Fluent::Plugin::CopyOutput).configure(conf)
38
40
  end
39
41
 
40
42
  def test_configure
@@ -42,158 +44,117 @@ class CopyOutputTest < Test::Unit::TestCase
42
44
 
43
45
  outputs = d.instance.outputs
44
46
  assert_equal 3, outputs.size
45
- assert_equal Fluent::TestOutput, outputs[0].class
46
- assert_equal Fluent::TestOutput, outputs[1].class
47
- assert_equal Fluent::TestOutput, outputs[2].class
47
+ assert_equal Fluent::Plugin::TestOutput, outputs[0].class
48
+ assert_equal Fluent::Plugin::Test2Output, outputs[1].class
49
+ assert_equal Fluent::Plugin::TestOutput, outputs[2].class
48
50
  assert_equal "c0", outputs[0].name
49
51
  assert_equal "c1", outputs[1].name
50
52
  assert_equal "c2", outputs[2].name
51
53
  end
52
54
 
53
- def test_emit
55
+ def test_feed_events
54
56
  d = create_driver
55
57
 
56
- time = Time.parse("2011-01-02 13:14:15 UTC").to_i
57
- d.emit({"a"=>1}, time)
58
- d.emit({"a"=>2}, time)
58
+ assert !d.instance.outputs[0].has_router?
59
+ assert_not_nil d.instance.outputs[1].router
60
+ assert !d.instance.outputs[2].has_router?
59
61
 
60
- d.instance.outputs.each {|o|
61
- assert_equal [
62
- [time, {"a"=>1}],
63
- [time, {"a"=>2}],
64
- ], o.events
65
- }
62
+ time = event_time("2011-01-02 13:14:15 UTC")
63
+ d.run(default_tag: 'test') do
64
+ d.feed(time, {"a" => 1})
65
+ d.feed(time, {"a" => 2})
66
+ end
66
67
 
67
68
  d.instance.outputs.each {|o|
68
- assert_not_nil o.router
69
+ assert_equal [ [time, {"a"=>1}], [time, {"a"=>2}] ], o.events
69
70
  }
70
71
  end
71
72
 
72
- def test_msgpack_es_emit_bug
73
- d = Fluent::Test::OutputTestDriver.new(Fluent::CopyOutput)
74
-
75
- outputs = %w(p1 p2).map do |pname|
76
- p = Fluent::Plugin.new_output('test')
77
- p.configure('name' => pname)
78
- p.define_singleton_method(:emit) do |tag, es, chain|
79
- es.each do |time, record|
80
- super(tag, [[time, record]], chain)
81
- end
82
- end
83
- p
84
- end
85
-
86
- d.instance.instance_eval { @outputs = outputs }
73
+ def test_msgpack_unpacker_cache_bug_for_msgpack_event_stream
74
+ d = create_driver
87
75
 
88
- es = if defined?(MessagePack::Packer)
89
- time = Time.parse("2013-05-26 06:37:22 UTC").to_i
90
- packer = Fluent::Engine.msgpack_factory.packer
91
- packer.pack([time, {"a" => 1}])
92
- packer.pack([time, {"a" => 2}])
93
- Fluent::MessagePackEventStream.new(packer.to_s)
94
- else
95
- events = "#{[time, {"a" => 1}].to_msgpack}#{[time, {"a" => 2}].to_msgpack}"
96
- Fluent::MessagePackEventStream.new(events)
97
- end
76
+ time = event_time("2011-01-02 13:14:15 UTC")
77
+ source = Fluent::ArrayEventStream.new([ [time, {"a" => 1}], [time, {"a" => 2}] ])
78
+ es = Fluent::MessagePackEventStream.new(source.to_msgpack_stream)
98
79
 
99
- d.instance.emit('test', es, Fluent::NullOutputChain.instance)
80
+ d.run(default_tag: 'test') do
81
+ d.feed(es)
82
+ end
100
83
 
101
84
  d.instance.outputs.each { |o|
102
- assert_equal [
103
- [time, {"a"=>1}],
104
- [time, {"a"=>2}],
105
- ], o.events
85
+ assert_equal [ [time, {"a"=>1}], [time, {"a"=>2}] ], o.events
106
86
  }
107
87
  end
108
88
 
109
- def create_event_test_driver(is_deep_copy = false)
110
- deep_copy_config = %[
111
- deep_copy #{is_deep_copy}
112
- <store>
113
- type test
114
- name c0
115
- </store>
116
- <store>
117
- type test
118
- name c1
119
- </store>
120
- <store>
121
- type test
122
- name c2
123
- </store>
124
- ]
125
-
126
- output1 = Fluent::Plugin.new_output('test')
127
- output1.configure('name' => 'output1')
128
- output1.define_singleton_method(:emit) do |tag, es, chain|
89
+ def create_event_test_driver(does_deep_copy = false)
90
+ config = %[
91
+ deep_copy #{does_deep_copy}
92
+ <store>
93
+ @type test
94
+ name output1
95
+ </store>
96
+ <store>
97
+ @type test
98
+ name output2
99
+ </store>
100
+ ]
101
+
102
+ d = Fluent::Test::Driver::MultiOutput.new(Fluent::Plugin::CopyOutput).configure(config)
103
+ d.instance.outputs[0].define_singleton_method(:process) do |tag, es|
129
104
  es.each do |time, record|
130
105
  record['foo'] = 'bar'
131
- super(tag, [[time, record]], chain)
132
- end
133
- end
134
-
135
- output2 = Fluent::Plugin.new_output('test')
136
- output2.configure('name' => 'output2')
137
- output2.define_singleton_method(:emit) do |tag, es, chain|
138
- es.each do |time, record|
139
- super(tag, [[time, record]], chain)
140
106
  end
107
+ super(tag, es)
141
108
  end
142
-
143
- outputs = [output1, output2]
144
-
145
- d = Fluent::Test::OutputTestDriver.new(Fluent::CopyOutput)
146
- d = d.configure(deep_copy_config)
147
- d.instance.instance_eval { @outputs = outputs }
148
109
  d
149
110
  end
150
111
 
151
- def test_one_event
152
- time = Time.parse("2013-05-26 06:37:22 UTC").to_i
153
-
154
- d = create_event_test_driver(false)
155
- es = Fluent::OneEventStream.new(time, {"a" => 1})
156
- d.instance.emit('test', es, Fluent::NullOutputChain.instance)
157
-
158
- assert_equal [
159
- [[time, {"a"=>1, "foo"=>"bar"}]],
160
- [[time, {"a"=>1, "foo"=>"bar"}]]
161
- ], d.instance.outputs.map{ |o| o.events }
112
+ time = event_time("2013-05-26 06:37:22 UTC")
113
+ mes0 = Fluent::MultiEventStream.new
114
+ mes0.add(time, {"a" => 1})
115
+ mes0.add(time, {"b" => 1})
116
+ mes1 = Fluent::MultiEventStream.new
117
+ mes1.add(time, {"a" => 1})
118
+ mes1.add(time, {"b" => 1})
119
+
120
+ data(
121
+ "OneEventStream without deep_copy" => [false, Fluent::OneEventStream.new(time, {"a" => 1})],
122
+ "OneEventStream with deep_copy" => [true, Fluent::OneEventStream.new(time, {"a" => 1})],
123
+ "ArrayEventStream without deep_copy" => [false, Fluent::ArrayEventStream.new([ [time, {"a" => 1}], [time, {"b" => 2}] ])],
124
+ "ArrayEventStream with deep_copy" => [true, Fluent::ArrayEventStream.new([ [time, {"a" => 1}], [time, {"b" => 2}] ])],
125
+ "MultiEventStream without deep_copy" => [false, mes0],
126
+ "MultiEventStream with deep_copy" => [true, mes1],
127
+ )
128
+ def test_deep_copy_controls_shallow_or_deep_copied(data)
129
+ does_deep_copy, es = data
130
+
131
+ d = create_event_test_driver(does_deep_copy)
132
+
133
+ d.run(default_tag: 'test') do
134
+ d.feed(es)
135
+ end
162
136
 
163
- d = create_event_test_driver(true)
164
- es = Fluent::OneEventStream.new(time, {"a" => 1})
165
- d.instance.emit('test', es, Fluent::NullOutputChain.instance)
137
+ events = d.instance.outputs.map(&:events)
166
138
 
167
- assert_equal [
168
- [[time, {"a"=>1, "foo"=>"bar"}]],
169
- [[time, {"a"=>1}]]
170
- ], d.instance.outputs.map{ |o| o.events }
171
- end
139
+ if does_deep_copy
140
+ events[0].each_with_index do |entry0, i|
141
+ record0 = entry0.last
142
+ record1 = events[1][i].last
172
143
 
173
- def test_multi_event
174
- time = Time.parse("2013-05-26 06:37:22 UTC").to_i
175
-
176
- d = create_event_test_driver(false)
177
- es = Fluent::MultiEventStream.new
178
- es.add(time, {"a" => 1})
179
- es.add(time, {"b" => 2})
180
- d.instance.emit('test', es, Fluent::NullOutputChain.instance)
181
-
182
- assert_equal [
183
- [[time, {"a"=>1, "foo"=>"bar"}], [time, {"b"=>2, "foo"=>"bar"}]],
184
- [[time, {"a"=>1, "foo"=>"bar"}], [time, {"b"=>2, "foo"=>"bar"}]]
185
- ], d.instance.outputs.map{ |o| o.events }
186
-
187
- d = create_event_test_driver(true)
188
- es = Fluent::MultiEventStream.new
189
- es.add(time, {"a" => 1})
190
- es.add(time, {"b" => 2})
191
- d.instance.emit('test', es, Fluent::NullOutputChain.instance)
192
-
193
- assert_equal [
194
- [[time, {"a"=>1, "foo"=>"bar"}], [time, {"b"=>2, "foo"=>"bar"}]],
195
- [[time, {"a"=>1}], [time, {"b"=>2}]]
196
- ], d.instance.outputs.map{ |o| o.events }
144
+ assert{ record0.object_id != record1.object_id }
145
+ assert_equal "bar", record0["foo"]
146
+ assert !record1.has_key?("foo")
147
+ end
148
+ else
149
+ events[0].each_with_index do |entry0, i|
150
+ record0 = entry0.last
151
+ record1 = events[1][i].last
152
+
153
+ assert{ record0.object_id == record1.object_id }
154
+ assert_equal "bar", record0["foo"]
155
+ assert_equal "bar", record1["foo"]
156
+ end
157
+ end
197
158
  end
198
159
  end
199
160