fluentd 0.14.3 → 0.14.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.

Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +59 -1131
  3. data/Rakefile +15 -0
  4. data/appveyor.yml +2 -2
  5. data/example/multi_filters.conf +61 -0
  6. data/fluentd.gemspec +19 -16
  7. data/lib/fluent/agent.rb +3 -0
  8. data/lib/fluent/command/debug.rb +4 -4
  9. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +2 -0
  10. data/lib/fluent/compat/output.rb +5 -2
  11. data/lib/fluent/config/configure_proxy.rb +26 -5
  12. data/lib/fluent/config/error.rb +3 -0
  13. data/lib/fluent/config/section.rb +15 -0
  14. data/lib/fluent/event_router.rb +77 -4
  15. data/lib/fluent/plugin/base.rb +12 -3
  16. data/lib/fluent/plugin/filter.rb +48 -6
  17. data/lib/fluent/plugin/filter_record_transformer.rb +3 -1
  18. data/lib/fluent/plugin/filter_stdout.rb +0 -4
  19. data/lib/fluent/plugin/in_debug_agent.rb +5 -5
  20. data/lib/fluent/plugin/in_dummy.rb +9 -1
  21. data/lib/fluent/plugin/in_forward.rb +32 -14
  22. data/lib/fluent/plugin/in_monitor_agent.rb +31 -77
  23. data/lib/fluent/plugin/in_tail.rb +37 -9
  24. data/lib/fluent/plugin/out_forward.rb +2 -13
  25. data/lib/fluent/plugin/output.rb +16 -1
  26. data/lib/fluent/plugin/storage_local.rb +16 -0
  27. data/lib/fluent/plugin_helper/timer.rb +6 -1
  28. data/lib/fluent/root_agent.rb +3 -0
  29. data/lib/fluent/supervisor.rb +62 -9
  30. data/lib/fluent/test/base.rb +3 -0
  31. data/lib/fluent/test/driver/base.rb +5 -0
  32. data/lib/fluent/test/formatter_test.rb +2 -0
  33. data/lib/fluent/test/parser_test.rb +2 -0
  34. data/lib/fluent/version.rb +1 -1
  35. data/lib/fluent/winsvc.rb +1 -2
  36. data/test/compat/test_calls_super.rb +2 -0
  37. data/test/config/test_configurable.rb +88 -0
  38. data/test/config/test_types.rb +7 -3
  39. data/test/plugin/test_filter.rb +121 -23
  40. data/test/plugin/test_filter_record_transformer.rb +22 -6
  41. data/test/plugin/test_in_debug_agent.rb +2 -2
  42. data/test/plugin/test_in_forward.rb +54 -6
  43. data/test/plugin/test_in_monitor_agent.rb +329 -0
  44. data/test/plugin/test_in_tail.rb +73 -0
  45. data/test/plugin/test_out_forward.rb +1 -0
  46. data/test/plugin/test_output.rb +53 -0
  47. data/test/plugin/test_output_as_buffered.rb +13 -0
  48. data/test/plugin/test_output_as_buffered_overflow.rb +3 -0
  49. data/test/plugin/test_output_as_buffered_retries.rb +11 -0
  50. data/test/plugin/test_output_as_buffered_secondary.rb +12 -0
  51. data/test/plugin/test_output_as_standard.rb +12 -0
  52. data/test/plugin_helper/test_compat_parameters.rb +2 -0
  53. data/test/plugin_helper/test_timer.rb +31 -0
  54. data/test/test_event_router.rb +87 -0
  55. data/test/test_filter.rb +48 -6
  56. data/test/test_log.rb +5 -2
  57. data/test/test_output.rb +41 -1
  58. data/test/test_plugin_classes.rb +17 -9
  59. data/test/test_root_agent.rb +146 -0
  60. metadata +51 -67
@@ -30,7 +30,7 @@ begin
30
30
  def read_fluentdopt
31
31
  require 'win32/Registry'
32
32
  Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM\\CurrentControlSet\\Services\\fluentdwinsvc") do |reg|
33
- reg.read("fluentdopt")[1]
33
+ reg.read("fluentdopt")[1] rescue ""
34
34
  end
35
35
  end
36
36
 
@@ -47,7 +47,6 @@ begin
47
47
  @pid = 0
48
48
 
49
49
  def service_main
50
- opt = read_fluentdopt
51
50
  @pid = service_main_start
52
51
  while running?
53
52
  sleep 10
@@ -32,12 +32,14 @@ class CompatCallsSuperTest < Test::Unit::TestCase
32
32
  end
33
33
  class DummyGoodFilter < Fluent::Filter
34
34
  def configure(conf); super; end
35
+ def filter(tag, time, record); end
35
36
  def start; super; end
36
37
  def before_shutdown; super; end
37
38
  def shutdown; super; end
38
39
  end
39
40
  class DummyBadFilter < Fluent::Filter
40
41
  def configure(conf); super; end
42
+ def filter(tag, time, record); end
41
43
  def start; end
42
44
  def before_shutdown; end
43
45
  def shutdown; end
@@ -342,6 +342,12 @@ module ConfigurableSpec
342
342
  config_param :size_of_something, :size, default: 128
343
343
  end
344
344
  end
345
+ class UnRecommended
346
+ include Fluent::Configurable
347
+ attr_accessor :log
348
+ config_param :key1, :string, default: 'deprecated', deprecated: "key1 will be removed."
349
+ config_param :key2, :string, default: 'obsoleted', obsoleted: "key2 has been removed."
350
+ end
345
351
  end
346
352
 
347
353
  module Fluent::Config
@@ -1102,5 +1108,87 @@ module Fluent::Config
1102
1108
  end
1103
1109
  end
1104
1110
  end
1111
+ sub_test_case 'non-required options for config_param' do
1112
+ test 'desc must be a string if specified' do
1113
+ assert_raise ArgumentError.new("key: desc must be a String, but Symbol") do
1114
+ class InvalidDescClass
1115
+ include Fluent::Configurable
1116
+ config_param :key, :string, default: '', desc: :invalid_description
1117
+ end
1118
+ end
1119
+ end
1120
+ test 'alias must be a symbol if specified' do
1121
+ assert_raise ArgumentError.new("key: alias must be a Symbol, but String") do
1122
+ class InvalidAliasClass
1123
+ include Fluent::Configurable
1124
+ config_param :key, :string, default: '', alias: 'yay'
1125
+ end
1126
+ end
1127
+ end
1128
+ test 'deprecated must be a string if specified' do
1129
+ assert_raise ArgumentError.new("key: deprecated must be a String, but TrueClass") do
1130
+ class InvalidDeprecatedClass
1131
+ include Fluent::Configurable
1132
+ config_param :key, :string, default: '', deprecated: true
1133
+ end
1134
+ end
1135
+ end
1136
+ test 'obsoleted must be a string if specified' do
1137
+ assert_raise ArgumentError.new("key: obsoleted must be a String, but TrueClass") do
1138
+ class InvalidObsoletedClass
1139
+ include Fluent::Configurable
1140
+ config_param :key, :string, default: '', obsoleted: true
1141
+ end
1142
+ end
1143
+ end
1144
+ test 'value_type for hash must be a symbol' do
1145
+ assert_raise ArgumentError.new("key: value_type must be a Symbol, but String") do
1146
+ class InvalidValueTypeOfHashClass
1147
+ include Fluent::Configurable
1148
+ config_param :key, :hash, value_type: 'yay'
1149
+ end
1150
+ end
1151
+ end
1152
+ test 'value_type for array must be a symbol' do
1153
+ assert_raise ArgumentError.new("key: value_type must be a Symbol, but String") do
1154
+ class InvalidValueTypeOfArrayClass
1155
+ include Fluent::Configurable
1156
+ config_param :key, :array, value_type: 'yay'
1157
+ end
1158
+ end
1159
+ end
1160
+ end
1161
+ sub_test_case 'enum parameters' do
1162
+ test 'list must be specified as an array of symbols'
1163
+ end
1164
+ sub_test_case 'deprecated/obsoleted parameters' do
1165
+ test 'both cannot be specified at once' do
1166
+ assert_raise ArgumentError.new("param1: both of deprecated and obsoleted cannot be specified at once") do
1167
+ class Buggy1
1168
+ include Fluent::Configurable
1169
+ config_param :param1, :string, default: '', deprecated: 'yay', obsoleted: 'foo!'
1170
+ end
1171
+ end
1172
+ end
1173
+
1174
+ test 'warned if deprecated parameter is configured' do
1175
+ obj = ConfigurableSpec::UnRecommended.new
1176
+ obj.log = Fluent::Test::TestLogger.new
1177
+ obj.configure(config_element('ROOT', '', {'key1' => 'yay'}, []))
1178
+
1179
+ assert_equal 'yay', obj.key1
1180
+ first_log = obj.log.logs.first
1181
+ assert{ first_log && first_log.include?("[warn]") && first_log.include?("'key1' parameter is deprecated: key1 will be removed.") }
1182
+ end
1183
+
1184
+ test 'error raised if obsoleted parameter is configured' do
1185
+ obj = ConfigurableSpec::UnRecommended.new
1186
+ obj.log = Fluent::Test::TestLogger.new
1187
+
1188
+ assert_raise Fluent::ObsoletedParameterError.new("'key2' parameter is already removed: key2 has been removed.") do
1189
+ obj.configure(config_element('ROOT', '', {'key2' => 'yay'}, []))
1190
+ end
1191
+ end
1192
+ end
1105
1193
  end
1106
1194
  end
@@ -72,9 +72,9 @@ class TestConfigTypes < ::Test::Unit::TestCase
72
72
  assert_equal :val, Config::ENUM_TYPE.call('val', {list: [:val, :value, :v]})
73
73
  assert_equal :v, Config::ENUM_TYPE.call('v', {list: [:val, :value, :v]})
74
74
  assert_equal :value, Config::ENUM_TYPE.call('value', {list: [:val, :value, :v]})
75
- assert_raises(Fluent::ConfigError){ Config::ENUM_TYPE.call('x', {list: [:val, :value, :v]}) }
76
- assert_raises(RuntimeError){ Config::ENUM_TYPE.call('val', {}) }
77
- assert_raises(RuntimeError){ Config::ENUM_TYPE.call('val', {list: ["val", "value", "v"]}) }
75
+ assert_raises(Fluent::ConfigError.new("valid options are val,value,v but got x")){ Config::ENUM_TYPE.call('x', {list: [:val, :value, :v]}) }
76
+ assert_raises(RuntimeError.new("Plugin BUG: config type 'enum' requires :list of symbols")){ Config::ENUM_TYPE.call('val', {}) }
77
+ assert_raises(RuntimeError.new("Plugin BUG: config type 'enum' requires :list of symbols")){ Config::ENUM_TYPE.call('val', {list: ["val", "value", "v"]}) }
78
78
  end
79
79
 
80
80
  test 'integer' do
@@ -138,6 +138,8 @@ class TestConfigTypes < ::Test::Unit::TestCase
138
138
 
139
139
  assert_equal({"x"=>1,"y"=>60,"z"=>3600}, Config::HASH_TYPE.call('{"x":"1s","y":"1m","z":"1h"}', {value_type: :time}))
140
140
  assert_equal({"x"=>1,"y"=>60,"z"=>3600}, Config::HASH_TYPE.call('x:1s,y:1m,z:1h', {value_type: :time}))
141
+
142
+ assert_raise(RuntimeError.new("unknown type in REFORMAT: foo")){ Config::HASH_TYPE.call("x:1,y:2", {value_type: :foo}) }
141
143
  end
142
144
 
143
145
  test 'array' do
@@ -162,6 +164,8 @@ class TestConfigTypes < ::Test::Unit::TestCase
162
164
  }
163
165
  assert_equal(["1","2"], Config::ARRAY_TYPE.call('["1","2"]', array_options))
164
166
  assert_equal(["3"], Config::ARRAY_TYPE.call('["3"]', array_options))
167
+
168
+ assert_raise(RuntimeError.new("unknown type in REFORMAT: foo")){ Config::ARRAY_TYPE.call("1,2", {value_type: :foo}) }
165
169
  end
166
170
  end
167
171
  end
@@ -30,6 +30,27 @@ module FluentPluginFilterTest
30
30
  record
31
31
  end
32
32
  end
33
+ class NumDoublePluginWithTime < Fluent::Plugin::Filter
34
+ def filter_with_time(tag, time, record)
35
+ r = record.dup
36
+ r["num"] = r["num"].to_i * 2
37
+ [time, r]
38
+ end
39
+ end
40
+ class IgnoreForNumPluginWithTime < Fluent::Plugin::Filter
41
+ def filter_with_time(tag, time, record)
42
+ if record["num"].is_a? Numeric
43
+ nil
44
+ else
45
+ [time, record]
46
+ end
47
+ end
48
+ end
49
+ class InvalidPlugin < Fluent::Plugin::Filter
50
+ # Because of implemnting `filter_with_time` and `filter` methods
51
+ def filter_with_time(tag, time, record); end
52
+ def filter(tag, time, record); end
53
+ end
33
54
  end
34
55
 
35
56
  class FilterPluginTest < Test::Unit::TestCase
@@ -39,6 +60,10 @@ class FilterPluginTest < Test::Unit::TestCase
39
60
  end
40
61
  end
41
62
 
63
+ setup do
64
+ @p = nil
65
+ end
66
+
42
67
  teardown do
43
68
  if @p
44
69
  @p.stop unless @p.stopped?
@@ -53,12 +78,24 @@ class FilterPluginTest < Test::Unit::TestCase
53
78
  sub_test_case 'for basic dummy plugin' do
54
79
  setup do
55
80
  Fluent::Test.setup
56
- @p = FluentPluginFilterTest::DummyPlugin.new
81
+ end
82
+
83
+ test 'plugin does not define #filter raises error' do
84
+ assert_raise NotImplementedError do
85
+ FluentPluginFilterTest::DummyPlugin.new
86
+ end
87
+ end
88
+ end
89
+
90
+ sub_test_case 'normal filter plugin' do
91
+ setup do
92
+ Fluent::Test.setup
93
+ @p = FluentPluginFilterTest::NumDoublePlugin.new
57
94
  end
58
95
 
59
96
  test 'has healthy lifecycle' do
60
97
  assert !@p.configured?
61
- @p.configure(config_element())
98
+ @p.configure(config_element)
62
99
  assert @p.configured?
63
100
 
64
101
  assert !@p.started?
@@ -94,7 +131,7 @@ class FilterPluginTest < Test::Unit::TestCase
94
131
  assert @p.respond_to?(:plugin_id_configured?)
95
132
  assert @p.respond_to?(:plugin_id)
96
133
 
97
- @p.configure(config_element())
134
+ @p.configure(config_element)
98
135
 
99
136
  assert !@p.plugin_id_configured?
100
137
  assert @p.plugin_id
@@ -128,30 +165,13 @@ class FilterPluginTest < Test::Unit::TestCase
128
165
  end
129
166
  end
130
167
 
131
- test 'plugin does not define #filter raises error' do
132
- es = [
133
- [event_time('2016-04-19 13:01:00 -0700'), {"num" => "1", "message" => "Hello filters!"}],
134
- [event_time('2016-04-19 13:01:03 -0700'), {"num" => "2", "message" => "Hello filters!"}],
135
- [event_time('2016-04-19 13:01:05 -0700'), {"num" => "3", "message" => "Hello filters!"}],
136
- ]
137
- assert_raise NotImplementedError do
138
- @p.filter_stream('testing', es)
139
- end
140
- end
141
- end
142
-
143
- sub_test_case 'normal filter plugin' do
144
- setup do
145
- Fluent::Test.setup
146
- @p = FluentPluginFilterTest::NumDoublePlugin.new
147
- end
148
-
149
168
  test 'filters events correctly' do
150
169
  test_es = [
151
170
  [event_time('2016-04-19 13:01:00 -0700'), {"num" => "1", "message" => "Hello filters!"}],
152
171
  [event_time('2016-04-19 13:01:03 -0700'), {"num" => "2", "message" => "Hello filters!"}],
153
172
  [event_time('2016-04-19 13:01:05 -0700'), {"num" => "3", "message" => "Hello filters!"}],
154
173
  ]
174
+ @p.configure(config_element)
155
175
  es = @p.filter_stream('testing', test_es)
156
176
  assert es.is_a? Fluent::EventStream
157
177
 
@@ -186,6 +206,7 @@ class FilterPluginTest < Test::Unit::TestCase
186
206
  [event_time('2016-04-19 13:01:03 -0700'), {"num" => 2, "message" => "Ignored, yay!"}],
187
207
  [event_time('2016-04-19 13:01:05 -0700'), {"num" => "3", "message" => "Hello filters!"}],
188
208
  ]
209
+ @p.configure(config_element)
189
210
  es = @p.filter_stream('testing', test_es)
190
211
  assert es.is_a? Fluent::EventStream
191
212
 
@@ -213,8 +234,7 @@ class FilterPluginTest < Test::Unit::TestCase
213
234
 
214
235
  test 'has router and can emit events to error streams' do
215
236
  assert @p.has_router?
216
-
217
- @p.configure(config_element())
237
+ @p.configure(config_element)
218
238
  assert @p.router
219
239
 
220
240
  @p.router = DummyRouter.new([])
@@ -252,4 +272,82 @@ class FilterPluginTest < Test::Unit::TestCase
252
272
  assert_equal "Value of num is Number!", error_emits[0][3].message
253
273
  end
254
274
  end
275
+
276
+ sub_test_case 'filter plugins that is implmented `filter_with_time`' do
277
+ setup do
278
+ Fluent::Test.setup
279
+ @p = FluentPluginFilterTest::NumDoublePluginWithTime.new
280
+ end
281
+
282
+ test 'filters events correctly' do
283
+ test_es = [
284
+ [event_time('2016-04-19 13:01:00 -0700'), {"num" => "1", "message" => "Hello filters!"}],
285
+ [event_time('2016-04-19 13:01:03 -0700'), {"num" => "2", "message" => "Hello filters!"}],
286
+ [event_time('2016-04-19 13:01:05 -0700'), {"num" => "3", "message" => "Hello filters!"}],
287
+ ]
288
+ es = @p.filter_stream('testing', test_es)
289
+ assert es.is_a? Fluent::EventStream
290
+
291
+ ary = []
292
+ es.each do |time, r|
293
+ ary << [time, r]
294
+ end
295
+
296
+ assert_equal 3, ary.size
297
+
298
+ assert_equal event_time('2016-04-19 13:01:00 -0700'), ary[0][0]
299
+ assert_equal "Hello filters!", ary[0][1]["message"]
300
+ assert_equal 2, ary[0][1]["num"]
301
+
302
+ assert_equal event_time('2016-04-19 13:01:03 -0700'), ary[1][0]
303
+ assert_equal 4, ary[1][1]["num"]
304
+
305
+ assert_equal event_time('2016-04-19 13:01:05 -0700'), ary[2][0]
306
+ assert_equal 6, ary[2][1]["num"]
307
+ end
308
+ end
309
+
310
+ sub_test_case 'filter plugin that is implmented `filter_with_time` and returns nil for some records' do
311
+ setup do
312
+ Fluent::Test.setup
313
+ @p = FluentPluginFilterTest::IgnoreForNumPluginWithTime.new
314
+ end
315
+
316
+ test 'filter_stream ignores records which #filter_with_time return nil' do
317
+ test_es = [
318
+ [event_time('2016-04-19 13:01:00 -0700'), {"num" => "1", "message" => "Hello filters!"}],
319
+ [event_time('2016-04-19 13:01:03 -0700'), {"num" => 2, "message" => "Ignored, yay!"}],
320
+ [event_time('2016-04-19 13:01:05 -0700'), {"num" => "3", "message" => "Hello filters!"}],
321
+ ]
322
+ @p.configure(config_element)
323
+ es = @p.filter_stream('testing', test_es)
324
+ assert es.is_a? Fluent::EventStream
325
+
326
+ ary = []
327
+ es.each do |time, r|
328
+ ary << [time, r]
329
+ end
330
+
331
+ assert_equal 2, ary.size
332
+
333
+ assert_equal event_time('2016-04-19 13:01:00 -0700'), ary[0][0]
334
+ assert_equal "Hello filters!", ary[0][1]["message"]
335
+ assert_equal "1", ary[0][1]["num"]
336
+
337
+ assert_equal event_time('2016-04-19 13:01:05 -0700'), ary[1][0]
338
+ assert_equal "3", ary[1][1]["num"]
339
+ end
340
+ end
341
+
342
+ sub_test_case 'filter plugins that is implmented both `filter_with_time` and `filter`' do
343
+ setup do
344
+ Fluent::Test.setup
345
+ end
346
+
347
+ test 'raises DuplicatedImplementError' do
348
+ assert_raise do
349
+ FluentPluginFilterTest::InvalidPlugin.new
350
+ end
351
+ end
352
+ end
255
353
  end
@@ -174,12 +174,11 @@ class RecordTransformerFilterTest < Test::Unit::TestCase
174
174
  d = create_driver(config)
175
175
  yield d if block_given?
176
176
  d.run {
177
- msgs.each do |msg|
178
- record = {
179
- 'eventType0' => 'bar',
180
- 'message' => msg,
181
- }
182
- record = record.merge(msg) if msg.is_a?(Hash)
177
+ records = msgs.map do |msg|
178
+ next msg if msg.is_a?(Hash)
179
+ { 'eventType0' => 'bar', 'message' => msg }
180
+ end
181
+ records.each do |record|
183
182
  d.feed(@tag, @time, record)
184
183
  end
185
184
  }
@@ -273,6 +272,23 @@ class RecordTransformerFilterTest < Test::Unit::TestCase
273
272
  end
274
273
  end
275
274
 
275
+ test "Prevent overwriting reserved keys such as tag with enable_ruby #{enable_ruby}" do
276
+ config = %[
277
+ enable_ruby #{enable_ruby}
278
+ <record>
279
+ new_tag ${tag}
280
+ new_record_tag ${record["tag"]}
281
+ </record>
282
+ ]
283
+ records = [{'tag' => 'tag', 'time' => 'time'}]
284
+ filtered = filter(config, records)
285
+ filtered.each_with_index do |(_t, r), i|
286
+ assert_not_equal('tag', r['new_tag'])
287
+ assert_equal(@tag, r['new_tag'])
288
+ assert_equal('tag', r['new_record_tag'])
289
+ end
290
+ end
291
+
276
292
  test "hash values with placeholders with enable_ruby #{enable_ruby}" do
277
293
  config = %[
278
294
  enable_ruby #{enable_ruby}
@@ -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_debug_agent'
4
4
  require 'fileutils'
5
5
 
@@ -13,7 +13,7 @@ class DebugAgentInputTest < Test::Unit::TestCase
13
13
  TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/../tmp/in_debug_agent")
14
14
 
15
15
  def create_driver(conf = '')
16
- Fluent::Test::InputTestDriver.new(Fluent::DebugAgentInput).configure(conf)
16
+ Fluent::Test::Driver::Input.new(Fluent::Plugin::DebugAgentInput).configure(conf)
17
17
  end
18
18
 
19
19
  def test_unix_path_writable
@@ -29,6 +29,7 @@ class ForwardInputTest < Test::Unit::TestCase
29
29
  port #{PORT}
30
30
  bind 127.0.0.1
31
31
  ]
32
+ PEERADDR = ['?', '0000', '127.0.0.1', '127.0.0.1']
32
33
 
33
34
  def create_driver(conf=CONFIG)
34
35
  Fluent::Test::InputTestDriver.new(Fluent::ForwardInput).configure(conf)
@@ -260,7 +261,7 @@ class ForwardInputTest < Test::Unit::TestCase
260
261
 
261
262
  d.run do
262
263
  Fluent::Engine.msgpack_factory.unpacker.feed_each(chunk) do |obj|
263
- option = d.instance.send(:on_message, obj, chunk.size, "host: 127.0.0.1, addr: 127.0.0.1, port: 0000")
264
+ option = d.instance.send(:on_message, obj, chunk.size, PEERADDR)
264
265
  assert_equal option['size'], events.length
265
266
  end
266
267
  end
@@ -282,7 +283,7 @@ class ForwardInputTest < Test::Unit::TestCase
282
283
 
283
284
  d.run do
284
285
  Fluent::Engine.msgpack_factory.unpacker.feed_each(chunk) do |obj|
285
- d.instance.send(:on_message, obj, chunk.size, "host: 127.0.0.1, addr: 127.0.0.1, port: 0000")
286
+ d.instance.send(:on_message, obj, chunk.size, PEERADDR)
286
287
  end
287
288
  end
288
289
 
@@ -311,7 +312,7 @@ class ForwardInputTest < Test::Unit::TestCase
311
312
 
312
313
  d.run do
313
314
  Fluent::Engine.msgpack_factory.unpacker.feed_each(chunk) do |obj|
314
- d.instance.send(:on_message, obj, chunk.size, "host: 127.0.0.1, addr: 127.0.0.1, port: 0000")
315
+ d.instance.send(:on_message, obj, chunk.size, PEERADDR)
315
316
  end
316
317
  end
317
318
 
@@ -338,7 +339,7 @@ class ForwardInputTest < Test::Unit::TestCase
338
339
  # d.run => send_data
339
340
  d.run do
340
341
  Fluent::Engine.msgpack_factory.unpacker.feed_each(chunk) do |obj|
341
- d.instance.send(:on_message, obj, chunk.size, "host: 127.0.0.1, addr: 127.0.0.1, port: 0000")
342
+ d.instance.send(:on_message, obj, chunk.size, PEERADDR)
342
343
  end
343
344
  end
344
345
 
@@ -360,7 +361,7 @@ class ForwardInputTest < Test::Unit::TestCase
360
361
 
361
362
  # d.run => send_data
362
363
  d.run do
363
- d.instance.send(:on_message, data, 1000000000, "host: 127.0.0.1, addr: 127.0.0.1, port: 0000")
364
+ d.instance.send(:on_message, data, 1000000000, PEERADDR)
364
365
  end
365
366
 
366
367
  # check emitted data
@@ -476,7 +477,6 @@ class ForwardInputTest < Test::Unit::TestCase
476
477
 
477
478
  assert_equal events, d.emits
478
479
  assert_equal expected_acks, @responses.map { |res| JSON.parse(res)['ack'] }
479
-
480
480
  end
481
481
 
482
482
  def test_not_respond_to_message_not_requiring_ack
@@ -583,5 +583,53 @@ class ForwardInputTest < Test::Unit::TestCase
583
583
  @responses << res if try_to_receive_response
584
584
  end
585
585
 
586
+ # TODO: Use sub_test_case. Currently Errno::EADDRINUSE happens inside sub_test_case
587
+ test 'message protocol with source_hostname_key' do
588
+ execute_test { |events|
589
+ events.each { |tag, time, record|
590
+ send_data [tag, time, record].to_msgpack
591
+ }
592
+ }
593
+ end
594
+
595
+ test 'forward protocol with source_hostname_key' do
596
+ execute_test { |events|
597
+ entries = []
598
+ events.each {|tag,time,record|
599
+ entries << [time, record]
600
+ }
601
+ send_data ['tag1', entries].to_msgpack
602
+ }
603
+ end
604
+
605
+ test 'packed forward protocol with source_hostname_key' do
606
+ execute_test { |events|
607
+ entries = ''
608
+ events.each { |tag, time, record|
609
+ Fluent::Engine.msgpack_factory.packer(entries).write([time, record]).flush
610
+ }
611
+ send_data Fluent::Engine.msgpack_factory.packer.write(["tag1", entries]).to_s
612
+ }
613
+ end
614
+
615
+ def execute_test(&block)
616
+ d = create_driver(CONFIG + 'source_hostname_key source')
617
+
618
+ time = Fluent::EventTime.parse("2011-01-02 13:14:15 UTC")
619
+ events = [
620
+ ["tag1", time, {"a"=>1}],
621
+ ["tag1", time, {"a"=>2}]
622
+ ]
623
+ d.expected_emits_length = events.length
624
+
625
+ d.run do
626
+ block.call(events)
627
+ end
628
+
629
+ d.emits.each { |tag, _time, record|
630
+ assert_true record.has_key?('source')
631
+ }
632
+ end
633
+
586
634
  # TODO heartbeat
587
635
  end