fluentd 0.12.40 → 0.14.0

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 (252) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +6 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +33 -21
  5. data/CONTRIBUTING.md +1 -0
  6. data/ChangeLog +810 -237
  7. data/README.md +0 -25
  8. data/Rakefile +2 -1
  9. data/Vagrantfile +17 -0
  10. data/appveyor.yml +35 -0
  11. data/example/filter_stdout.conf +5 -5
  12. data/example/in_forward.conf +2 -2
  13. data/example/in_http.conf +2 -2
  14. data/example/in_out_forward.conf +17 -0
  15. data/example/in_syslog.conf +2 -2
  16. data/example/in_tail.conf +2 -2
  17. data/example/in_tcp.conf +2 -2
  18. data/example/in_udp.conf +2 -2
  19. data/example/out_copy.conf +4 -4
  20. data/example/out_file.conf +2 -2
  21. data/example/out_forward.conf +2 -2
  22. data/example/out_forward_buf_file.conf +23 -0
  23. data/example/v0_12_filter.conf +8 -8
  24. data/fluent.conf +29 -0
  25. data/fluentd.gemspec +18 -11
  26. data/lib/fluent/agent.rb +60 -58
  27. data/lib/fluent/command/cat.rb +1 -1
  28. data/lib/fluent/command/debug.rb +7 -5
  29. data/lib/fluent/command/fluentd.rb +97 -2
  30. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  31. data/lib/fluent/compat/filter.rb +50 -0
  32. data/lib/fluent/compat/formatter.rb +109 -0
  33. data/lib/fluent/compat/input.rb +50 -0
  34. data/lib/fluent/compat/output.rb +617 -0
  35. data/lib/fluent/compat/output_chain.rb +60 -0
  36. data/lib/fluent/compat/parser.rb +163 -0
  37. data/lib/fluent/compat/propagate_default.rb +62 -0
  38. data/lib/fluent/config.rb +23 -20
  39. data/lib/fluent/config/configure_proxy.rb +119 -70
  40. data/lib/fluent/config/dsl.rb +5 -18
  41. data/lib/fluent/config/element.rb +72 -8
  42. data/lib/fluent/config/error.rb +0 -3
  43. data/lib/fluent/config/literal_parser.rb +0 -2
  44. data/lib/fluent/config/parser.rb +4 -4
  45. data/lib/fluent/config/section.rb +39 -28
  46. data/lib/fluent/config/types.rb +2 -13
  47. data/lib/fluent/config/v1_parser.rb +1 -3
  48. data/lib/fluent/configurable.rb +48 -16
  49. data/lib/fluent/daemon.rb +15 -0
  50. data/lib/fluent/engine.rb +26 -52
  51. data/lib/fluent/env.rb +6 -4
  52. data/lib/fluent/event.rb +58 -11
  53. data/lib/fluent/event_router.rb +5 -5
  54. data/lib/fluent/filter.rb +2 -50
  55. data/lib/fluent/formatter.rb +4 -293
  56. data/lib/fluent/input.rb +2 -32
  57. data/lib/fluent/label.rb +2 -2
  58. data/lib/fluent/load.rb +3 -2
  59. data/lib/fluent/log.rb +107 -38
  60. data/lib/fluent/match.rb +0 -36
  61. data/lib/fluent/mixin.rb +117 -7
  62. data/lib/fluent/msgpack_factory.rb +62 -0
  63. data/lib/fluent/output.rb +7 -612
  64. data/lib/fluent/output_chain.rb +23 -0
  65. data/lib/fluent/parser.rb +4 -800
  66. data/lib/fluent/plugin.rb +100 -121
  67. data/lib/fluent/plugin/bare_output.rb +63 -0
  68. data/lib/fluent/plugin/base.rb +121 -0
  69. data/lib/fluent/plugin/buf_file.rb +101 -182
  70. data/lib/fluent/plugin/buf_memory.rb +9 -92
  71. data/lib/fluent/plugin/buffer.rb +473 -0
  72. data/lib/fluent/plugin/buffer/chunk.rb +135 -0
  73. data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
  74. data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
  75. data/lib/fluent/plugin/exec_util.rb +80 -75
  76. data/lib/fluent/plugin/file_util.rb +33 -28
  77. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  78. data/lib/fluent/plugin/filter.rb +51 -0
  79. data/lib/fluent/plugin/filter_grep.rb +13 -40
  80. data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
  81. data/lib/fluent/plugin/formatter.rb +93 -0
  82. data/lib/fluent/plugin/formatter_csv.rb +48 -0
  83. data/lib/fluent/plugin/formatter_hash.rb +32 -0
  84. data/lib/fluent/plugin/formatter_json.rb +47 -0
  85. data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
  86. data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
  87. data/lib/fluent/plugin/formatter_out_file.rb +45 -0
  88. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  89. data/lib/fluent/plugin/formatter_stdout.rb +39 -0
  90. data/lib/fluent/plugin/in_debug_agent.rb +4 -0
  91. data/lib/fluent/plugin/in_dummy.rb +22 -18
  92. data/lib/fluent/plugin/in_exec.rb +18 -8
  93. data/lib/fluent/plugin/in_forward.rb +36 -79
  94. data/lib/fluent/plugin/in_gc_stat.rb +4 -0
  95. data/lib/fluent/plugin/in_http.rb +21 -18
  96. data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
  97. data/lib/fluent/plugin/in_object_space.rb +6 -1
  98. data/lib/fluent/plugin/in_stream.rb +7 -3
  99. data/lib/fluent/plugin/in_syslog.rb +46 -95
  100. data/lib/fluent/plugin/in_tail.rb +51 -595
  101. data/lib/fluent/plugin/in_tcp.rb +8 -1
  102. data/lib/fluent/plugin/in_udp.rb +8 -14
  103. data/lib/fluent/plugin/input.rb +33 -0
  104. data/lib/fluent/plugin/multi_output.rb +95 -0
  105. data/lib/fluent/plugin/out_buffered_null.rb +59 -0
  106. data/lib/fluent/plugin/out_copy.rb +11 -7
  107. data/lib/fluent/plugin/out_exec.rb +15 -11
  108. data/lib/fluent/plugin/out_exec_filter.rb +18 -10
  109. data/lib/fluent/plugin/out_file.rb +34 -5
  110. data/lib/fluent/plugin/out_forward.rb +19 -9
  111. data/lib/fluent/plugin/out_null.rb +0 -14
  112. data/lib/fluent/plugin/out_roundrobin.rb +11 -7
  113. data/lib/fluent/plugin/out_stdout.rb +5 -7
  114. data/lib/fluent/plugin/out_stream.rb +3 -1
  115. data/lib/fluent/plugin/output.rb +979 -0
  116. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  117. data/lib/fluent/plugin/parser.rb +244 -0
  118. data/lib/fluent/plugin/parser_apache.rb +24 -0
  119. data/lib/fluent/plugin/parser_apache2.rb +84 -0
  120. data/lib/fluent/plugin/parser_apache_error.rb +21 -0
  121. data/lib/fluent/plugin/parser_csv.rb +31 -0
  122. data/lib/fluent/plugin/parser_json.rb +79 -0
  123. data/lib/fluent/plugin/parser_ltsv.rb +50 -0
  124. data/lib/fluent/plugin/parser_multiline.rb +102 -0
  125. data/lib/fluent/plugin/parser_nginx.rb +24 -0
  126. data/lib/fluent/plugin/parser_none.rb +36 -0
  127. data/lib/fluent/plugin/parser_syslog.rb +82 -0
  128. data/lib/fluent/plugin/parser_tsv.rb +37 -0
  129. data/lib/fluent/plugin/socket_util.rb +120 -114
  130. data/lib/fluent/plugin/storage.rb +84 -0
  131. data/lib/fluent/plugin/storage_local.rb +116 -0
  132. data/lib/fluent/plugin/string_util.rb +16 -13
  133. data/lib/fluent/plugin_helper.rb +39 -0
  134. data/lib/fluent/plugin_helper/child_process.rb +298 -0
  135. data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
  136. data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
  137. data/lib/fluent/plugin_helper/event_loop.rb +118 -0
  138. data/lib/fluent/plugin_helper/retry_state.rb +177 -0
  139. data/lib/fluent/plugin_helper/storage.rb +308 -0
  140. data/lib/fluent/plugin_helper/thread.rb +147 -0
  141. data/lib/fluent/plugin_helper/timer.rb +85 -0
  142. data/lib/fluent/plugin_id.rb +63 -0
  143. data/lib/fluent/process.rb +21 -30
  144. data/lib/fluent/registry.rb +21 -9
  145. data/lib/fluent/root_agent.rb +115 -40
  146. data/lib/fluent/supervisor.rb +330 -320
  147. data/lib/fluent/system_config.rb +42 -18
  148. data/lib/fluent/test.rb +6 -1
  149. data/lib/fluent/test/base.rb +23 -3
  150. data/lib/fluent/test/driver/base.rb +247 -0
  151. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  152. data/lib/fluent/test/driver/filter.rb +35 -0
  153. data/lib/fluent/test/driver/input.rb +31 -0
  154. data/lib/fluent/test/driver/output.rb +78 -0
  155. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  156. data/lib/fluent/test/filter_test.rb +0 -1
  157. data/lib/fluent/test/formatter_test.rb +2 -1
  158. data/lib/fluent/test/input_test.rb +23 -17
  159. data/lib/fluent/test/output_test.rb +28 -39
  160. data/lib/fluent/test/parser_test.rb +1 -1
  161. data/lib/fluent/time.rb +104 -1
  162. data/lib/fluent/{status.rb → unique_id.rb} +15 -24
  163. data/lib/fluent/version.rb +1 -1
  164. data/lib/fluent/winsvc.rb +72 -0
  165. data/test/compat/test_calls_super.rb +164 -0
  166. data/test/config/test_config_parser.rb +83 -0
  167. data/test/config/test_configurable.rb +547 -274
  168. data/test/config/test_configure_proxy.rb +146 -29
  169. data/test/config/test_dsl.rb +3 -181
  170. data/test/config/test_element.rb +274 -0
  171. data/test/config/test_literal_parser.rb +1 -1
  172. data/test/config/test_section.rb +79 -7
  173. data/test/config/test_system_config.rb +21 -0
  174. data/test/config/test_types.rb +3 -26
  175. data/test/helper.rb +78 -8
  176. data/test/plugin/test_bare_output.rb +118 -0
  177. data/test/plugin/test_base.rb +75 -0
  178. data/test/plugin/test_buf_file.rb +420 -521
  179. data/test/plugin/test_buf_memory.rb +32 -194
  180. data/test/plugin/test_buffer.rb +981 -0
  181. data/test/plugin/test_buffer_chunk.rb +110 -0
  182. data/test/plugin/test_buffer_file_chunk.rb +770 -0
  183. data/test/plugin/test_buffer_memory_chunk.rb +265 -0
  184. data/test/plugin/test_filter.rb +255 -0
  185. data/test/plugin/test_filter_grep.rb +2 -73
  186. data/test/plugin/test_filter_record_transformer.rb +24 -68
  187. data/test/plugin/test_filter_stdout.rb +6 -6
  188. data/test/plugin/test_in_debug_agent.rb +2 -0
  189. data/test/plugin/test_in_dummy.rb +11 -17
  190. data/test/plugin/test_in_exec.rb +6 -25
  191. data/test/plugin/test_in_forward.rb +112 -151
  192. data/test/plugin/test_in_gc_stat.rb +2 -0
  193. data/test/plugin/test_in_http.rb +106 -157
  194. data/test/plugin/test_in_object_space.rb +21 -5
  195. data/test/plugin/test_in_stream.rb +14 -13
  196. data/test/plugin/test_in_syslog.rb +30 -275
  197. data/test/plugin/test_in_tail.rb +95 -234
  198. data/test/plugin/test_in_tcp.rb +14 -0
  199. data/test/plugin/test_in_udp.rb +21 -13
  200. data/test/plugin/test_input.rb +122 -0
  201. data/test/plugin/test_multi_output.rb +180 -0
  202. data/test/plugin/test_out_buffered_null.rb +79 -0
  203. data/test/plugin/test_out_copy.rb +15 -2
  204. data/test/plugin/test_out_exec.rb +75 -25
  205. data/test/plugin/test_out_exec_filter.rb +74 -8
  206. data/test/plugin/test_out_file.rb +61 -7
  207. data/test/plugin/test_out_forward.rb +92 -15
  208. data/test/plugin/test_out_roundrobin.rb +1 -0
  209. data/test/plugin/test_out_stdout.rb +22 -13
  210. data/test/plugin/test_out_stream.rb +18 -0
  211. data/test/plugin/test_output.rb +515 -0
  212. data/test/plugin/test_output_as_buffered.rb +1540 -0
  213. data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
  214. data/test/plugin/test_output_as_buffered_retries.rb +808 -0
  215. data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
  216. data/test/plugin/test_output_as_standard.rb +362 -0
  217. data/test/plugin/test_owned_by.rb +35 -0
  218. data/test/plugin/test_storage.rb +167 -0
  219. data/test/plugin/test_storage_local.rb +8 -0
  220. data/test/plugin_helper/test_child_process.rb +599 -0
  221. data/test/plugin_helper/test_compat_parameters.rb +175 -0
  222. data/test/plugin_helper/test_event_emitter.rb +51 -0
  223. data/test/plugin_helper/test_event_loop.rb +52 -0
  224. data/test/plugin_helper/test_retry_state.rb +399 -0
  225. data/test/plugin_helper/test_storage.rb +411 -0
  226. data/test/plugin_helper/test_thread.rb +164 -0
  227. data/test/plugin_helper/test_timer.rb +100 -0
  228. data/test/scripts/exec_script.rb +0 -6
  229. data/test/scripts/fluent/plugin/out_test.rb +3 -0
  230. data/test/test_config.rb +13 -4
  231. data/test/test_event.rb +24 -13
  232. data/test/test_event_router.rb +8 -7
  233. data/test/test_event_time.rb +187 -0
  234. data/test/test_formatter.rb +13 -51
  235. data/test/test_input.rb +1 -1
  236. data/test/test_log.rb +239 -16
  237. data/test/test_mixin.rb +1 -1
  238. data/test/test_output.rb +53 -66
  239. data/test/test_parser.rb +105 -323
  240. data/test/test_plugin_helper.rb +81 -0
  241. data/test/test_root_agent.rb +4 -52
  242. data/test/test_supervisor.rb +272 -0
  243. data/test/test_unique_id.rb +47 -0
  244. metadata +180 -54
  245. data/lib/fluent/buffer.rb +0 -365
  246. data/lib/fluent/plugin/filter_parser.rb +0 -107
  247. data/lib/fluent/plugin/in_status.rb +0 -76
  248. data/lib/fluent/test/helpers.rb +0 -86
  249. data/test/plugin/data/log/foo/bar2 +0 -0
  250. data/test/plugin/test_filter_parser.rb +0 -744
  251. data/test/plugin/test_in_status.rb +0 -38
  252. data/test/test_buffer.rb +0 -624
@@ -18,21 +18,6 @@ require 'fluent/configurable'
18
18
  require 'fluent/config/element'
19
19
 
20
20
  module Fluent
21
- module SystemConfigMixin
22
- def system_config
23
- @_system_config || Fluent::Engine.system_config
24
- end
25
-
26
- def system_config_override(opts={})
27
- unless @_system_config
28
- @_system_config = Fluent::Engine.system_config.dup
29
- end
30
- opts.each_pair do |key, value|
31
- @_system_config.send(:"#{key.to_s}=", value)
32
- end
33
- end
34
- end
35
-
36
21
  class SystemConfig
37
22
  include Configurable
38
23
 
@@ -46,11 +31,15 @@ module Fluent
46
31
  config_param :rpc_endpoint, :string, default: nil
47
32
  config_param :enable_get_dump, :bool, default: nil
48
33
  config_param :process_name, default: nil
34
+ config_param :file_permission, default: nil do |v|
35
+ v.to_i(8)
36
+ end
37
+ config_param :dir_permission, default: nil do |v|
38
+ v.to_i(8)
39
+ end
49
40
 
50
41
  def self.create(conf)
51
- systems = conf.elements.select { |e|
52
- e.name == 'system'
53
- }
42
+ systems = conf.elements(name: 'system')
54
43
  return SystemConfig.new if systems.empty?
55
44
  raise Fluent::ConfigError, "<system> is duplicated. <system> should be only one" if systems.size > 1
56
45
 
@@ -61,6 +50,16 @@ module Fluent
61
50
  Fluent::Config::Element.new('<SYSTEM>', '', {}, [])
62
51
  end
63
52
 
53
+ def self.overwrite_system_config(hash)
54
+ older = defined?($_system_config) ? $_system_config : nil
55
+ begin
56
+ $_system_config = SystemConfig.new(Fluent::Config::Element.new('system', '', hash, []))
57
+ yield
58
+ ensure
59
+ $_system_config = older
60
+ end
61
+ end
62
+
64
63
  def initialize(conf=nil)
65
64
  super()
66
65
  conf ||= SystemConfig.blank_system_config
@@ -77,6 +76,8 @@ module Fluent
77
76
  s.rpc_endpoint = @rpc_endpoint
78
77
  s.enable_get_dump = @enable_get_dump
79
78
  s.process_name = @process_name
79
+ s.file_permission = @file_permission
80
+ s.dir_permission = @dir_permission
80
81
 
81
82
  s
82
83
  end
@@ -92,7 +93,30 @@ module Fluent
92
93
  @rpc_endpoint = system.rpc_endpoint unless system.rpc_endpoint.nil?
93
94
  @enable_get_dump = system.enable_get_dump unless system.enable_get_dump.nil?
94
95
  @process_name = system.process_name unless system.process_name.nil?
96
+ @file_permission = system.file_permission unless system.file_permission.nil?
97
+ @dir_permission = system.dir_permission unless system.dir_permission.nil?
95
98
  }
96
99
  end
100
+
101
+ module Mixin
102
+ def system_config
103
+ require 'fluent/engine'
104
+ unless defined?($_system_config)
105
+ $_system_config = nil
106
+ end
107
+ (instance_variable_defined?("@_system_config") && @_system_config) ||
108
+ $_system_config || Fluent::Engine.system_config
109
+ end
110
+
111
+ def system_config_override(opts={})
112
+ require 'fluent/engine'
113
+ if !instance_variable_defined?("@_system_config") || @_system_config.nil?
114
+ @_system_config = (defined?($_system_config) && $_system_config ? $_system_config : Fluent::Engine.system_config).dup
115
+ end
116
+ opts.each_pair do |key, value|
117
+ @_system_config.send(:"#{key.to_s}=", value)
118
+ end
119
+ end
120
+ end
97
121
  end
98
122
  end
@@ -22,5 +22,10 @@ require 'fluent/test/output_test'
22
22
  require 'fluent/test/filter_test'
23
23
  require 'fluent/test/parser_test'
24
24
  require 'fluent/test/formatter_test'
25
+ require 'serverengine'
25
26
 
26
- $log ||= Fluent::Log.new(Fluent::Test::DummyLogDevice.new)
27
+ dl_opts = {}
28
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::INFO
29
+ logdev = Fluent::Test::DummyLogDevice.new
30
+ logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
31
+ $log ||= Fluent::Log.new(logger)
@@ -17,6 +17,7 @@
17
17
  require 'fluent/engine'
18
18
  require 'fluent/system_config'
19
19
  require 'fluent/config'
20
+ require 'serverengine'
20
21
 
21
22
  module Fluent
22
23
  module Test
@@ -25,10 +26,10 @@ module Fluent
25
26
  engine = Fluent.const_set(:Engine, EngineClass.new).init(SystemConfig.new)
26
27
 
27
28
  engine.define_singleton_method(:now=) {|n|
28
- @now = n.to_i
29
+ @now = n
29
30
  }
30
31
  engine.define_singleton_method(:now) {
31
- @now || super()
32
+ @now ||= super()
32
33
  }
33
34
 
34
35
  nil
@@ -91,6 +92,10 @@ module Fluent
91
92
  @logs = []
92
93
  end
93
94
 
95
+ def reset
96
+ @logs = []
97
+ end
98
+
94
99
  def tty?
95
100
  false
96
101
  end
@@ -115,7 +120,15 @@ module Fluent
115
120
  class TestLogger < Fluent::PluginLogger
116
121
  def initialize
117
122
  @logdev = DummyLogDevice.new
118
- super(Fluent::Log.new(@logdev))
123
+ dl_opts = {}
124
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::INFO
125
+ logger = ServerEngine::DaemonLogger.new(@logdev, dl_opts)
126
+ log = Fluent::Log.new(logger)
127
+ super(log)
128
+ end
129
+
130
+ def reset
131
+ @logdev.reset
119
132
  end
120
133
 
121
134
  def logs
@@ -124,3 +137,10 @@ module Fluent
124
137
  end
125
138
  end
126
139
  end
140
+
141
+ Test::Unit::Assertions.module_eval do
142
+ def assert_equal_event_time(a, b)
143
+ assert_equal(a.sec, b.sec)
144
+ assert_equal(a.nsec, b.nsec)
145
+ end
146
+ end
@@ -0,0 +1,247 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/test/driver/test_event_router'
18
+
19
+ require 'timeout'
20
+
21
+ module Fluent
22
+ module Test
23
+ module Driver
24
+ class Base
25
+ def initialize(klass, opts: {}, &block)
26
+ if klass.is_a?(Class)
27
+ if block
28
+ # Create new class for test w/ overwritten methods
29
+ # klass.dup is worse because its ancestors does NOT include original class name
30
+ klass = Class.new(klass)
31
+ klass.module_eval(&block)
32
+ end
33
+ @instance = klass.new
34
+ else
35
+ @instance = klass
36
+ end
37
+ if opts
38
+ @instance.system_config_override(opts)
39
+ end
40
+ @instance.log = TestLogger.new
41
+ @logs = @instance.log.out.logs
42
+
43
+ @run_post_conditions = []
44
+ @run_breaking_conditions = []
45
+
46
+ @broken = false
47
+
48
+ @event_streams = nil
49
+ @error_events = nil
50
+ end
51
+
52
+ attr_reader :instance, :logs
53
+
54
+ def configure(conf, syntax: :v1)
55
+ if conf.is_a?(Fluent::Config::Element)
56
+ @config = conf
57
+ else
58
+ @config = Config.parse(conf, "(test)", "(test_dir)", syntax: syntax)
59
+ end
60
+
61
+ if @instance.respond_to?(:router=)
62
+ @event_streams = []
63
+ @error_events = []
64
+
65
+ driver = self
66
+ mojule = Module.new do
67
+ define_method(:event_emitter_router) do |label_name|
68
+ TestEventRouter.new(driver)
69
+ end
70
+ end
71
+ @instance.singleton_class.module_eval do
72
+ prepend mojule
73
+ end
74
+ end
75
+
76
+ @instance.configure(@config)
77
+ self
78
+ end
79
+
80
+ def end_if(&block)
81
+ raise ArgumentError, "block is not given" unless block_given?
82
+ @run_post_conditions << block
83
+ end
84
+
85
+ def break_if(&block)
86
+ raise ArgumentError, "block is not given" unless block_given?
87
+ @run_breaking_conditions << block
88
+ end
89
+
90
+ def broken?
91
+ @broken
92
+ end
93
+
94
+ Emit = Struct.new(:tag, :es)
95
+ ErrorEvent = Struct.new(:tag, :time, :record, :error)
96
+
97
+ # via TestEventRouter
98
+ def emit_event_stream(tag, es)
99
+ @event_streams << Emit.new(tag, es)
100
+ end
101
+
102
+ def emit_error_event(tag, time, record, error)
103
+ @error_events << ErrorEvent.new(tag, time, record, error)
104
+ end
105
+
106
+ def events(tag: nil)
107
+ selected = @event_streams.select{|e| tag.nil? ? true : e.tag == tag }
108
+ if block_given?
109
+ selected.each do |e|
110
+ e.es.each do |time, record|
111
+ yield e.tag, time, record
112
+ end
113
+ end
114
+ else
115
+ list = []
116
+ selected.each do |e|
117
+ e.es.each do |time, record|
118
+ list << [e.tag, time, record]
119
+ end
120
+ end
121
+ list
122
+ end
123
+ end
124
+
125
+ def error_events(tag: nil)
126
+ selected = @error_events.select{|e| tag.nil? ? true : e.tag == tag }
127
+ if block_given?
128
+ selected.each do |e|
129
+ yield e.tag, e.time, e.record, e.error
130
+ end
131
+ else
132
+ selected.map{|e| [e.tag, e.time, e.record, e.error] }
133
+ end
134
+ end
135
+
136
+ def run(expect_emits: nil, expect_records: nil, timeout: nil, start: true, shutdown: true, &block)
137
+ instance_start if start
138
+
139
+ if @instance.respond_to?(:thread_wait_until_start)
140
+ @instance.thread_wait_until_start
141
+ end
142
+ if @instance.respond_to?(:event_loop_wait_until_start)
143
+ @instance.event_loop_wait_until_start
144
+ end
145
+
146
+ begin
147
+ run_actual(expect_emits: expect_emits, expect_records: expect_records, timeout: timeout, &block)
148
+ ensure
149
+ instance_shutdown if shutdown
150
+ end
151
+ end
152
+
153
+ def instance_start
154
+ unless @instance.started?
155
+ @instance.start
156
+ instance_hook_after_started
157
+ end
158
+ end
159
+
160
+ def instance_hook_after_started
161
+ # insert hooks for tests available after instance.start
162
+ end
163
+
164
+ def instance_shutdown
165
+ @instance.stop unless @instance.stopped?
166
+ @instance.before_shutdown unless @instance.before_shutdown?
167
+ @instance.shutdown unless @instance.shutdown?
168
+
169
+ if @instance.respond_to?(:event_loop_wait_until_stop)
170
+ @instance.event_loop_wait_until_stop
171
+ end
172
+
173
+ @instance.after_shutdown unless @instance.after_shutdown?
174
+ @instance.close unless @instance.closed?
175
+
176
+ if @instance.respond_to?(:thread_wait_until_stop)
177
+ @instance.thread_wait_until_stop
178
+ end
179
+
180
+ @instance.terminate unless @instance.terminated?
181
+ end
182
+
183
+ def run_actual(expect_emits: nil, expect_records: nil, timeout: nil, &block)
184
+ if @instance.respond_to?(:_threads)
185
+ until @instance._threads.values.all?(&:alive?)
186
+ sleep 0.01
187
+ end
188
+ end
189
+
190
+ if @instance.respond_to?(:event_loop_running?)
191
+ until @instance.event_loop_running?
192
+ sleep 0.01
193
+ end
194
+ end
195
+
196
+ if expect_emits
197
+ @run_post_conditions << ->(){ @emit_streams.size >= expect_emits }
198
+ end
199
+ if expect_records
200
+ @run_post_conditions << ->(){ @emit_streams.reduce(0){|a, e| a + e.es.size } >= expected_records }
201
+ end
202
+ if timeout
203
+ stop_at = Time.now + timeout
204
+ @run_breaking_conditions << ->(){ Time.now >= stop_at }
205
+ end
206
+
207
+ if !block_given? && @run_post_conditions.empty? && @run_breaking_conditions.empty?
208
+ raise ArgumentError, "no stop conditions nor block specified"
209
+ end
210
+
211
+ if !block_given?
212
+ block = ->(){ sleep(0.1) until stop? }
213
+ end
214
+
215
+ if timeout
216
+ begin
217
+ Timeout.timeout(timeout * 1.1) do |sec|
218
+ block.call
219
+ end
220
+ rescue Timeout::Error
221
+ @broken = true
222
+ end
223
+ else
224
+ block.call
225
+ end
226
+ end
227
+
228
+ def stop?
229
+ # Should stop running if post conditions are not registered.
230
+ return true unless @run_post_conditions
231
+
232
+ # Should stop running if all of the post conditions are true.
233
+ return true if @run_post_conditions.all? {|proc| proc.call }
234
+
235
+ # Should stop running if some of the breaking conditions is true.
236
+ # In this case, some post conditions may be not true.
237
+ if @run_breaking_conditions.any? {|proc| proc.call }
238
+ @broken = true
239
+ return true
240
+ end
241
+
242
+ false
243
+ end
244
+ end
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,98 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/event'
18
+ require 'fluent/time'
19
+
20
+ module Fluent
21
+ module Test
22
+ module Driver
23
+ module EventFeeder
24
+ def initialize(klass, opts: {}, &block)
25
+ super
26
+ @default_tag = nil
27
+ @feed_method = nil
28
+ end
29
+
30
+ def run(default_tag: nil, **kwargs, &block)
31
+ @feed_method = if @instance.respond_to?(:filter_stream)
32
+ :filter_stream
33
+ else
34
+ :emit_events
35
+ end
36
+ if default_tag
37
+ @default_tag = default_tag
38
+ end
39
+ super(**kwargs, &block)
40
+ end
41
+
42
+ def feed_to_plugin(tag, es)
43
+ @instance.__send__(@feed_method, tag, es)
44
+ end
45
+
46
+ # d.run do
47
+ # d.feed('tag', time, {record})
48
+ # d.feed('tag', [ [time, {record}], [time, {record}], ... ])
49
+ # d.feed('tag', es)
50
+ # end
51
+ # d.run(default_tag: 'tag') do
52
+ # d.feed({record})
53
+ # d.feed(time, {record})
54
+ # d.feed([ [time, {record}], [time, {record}], ... ])
55
+ # d.feed(es)
56
+ # end
57
+ def feed(*args)
58
+ case args.size
59
+ when 1
60
+ raise ArgumentError, "tag not specified without default_tag" unless @default_tag
61
+ case args.first
62
+ when Fluent::EventStream
63
+ feed_to_plugin(@default_tag, args.first)
64
+ when Array
65
+ feed_to_plugin(@default_tag, ArrayEventStream.new(args.first))
66
+ when Hash
67
+ record = args.first
68
+ time = Fluent::EventTime.now
69
+ feed_to_plugin(@default_tag, OneEventStream.new(time, record))
70
+ else
71
+ raise ArgumentError, "unexpected events object (neither event(Hash), EventStream nor Array): #{args.first.class}"
72
+ end
73
+ when 2
74
+ if args[0].is_a?(String) && (args[1].is_a?(Array) || args[1].is_a?(Fluent::EventStream))
75
+ tag, es = args
76
+ es = ArrayEventStream.new(es) if es.is_a?(Array)
77
+ feed_to_plugin(tag, es)
78
+ elsif @default_tag && (args[0].is_a?(Fluent::EventTime) || args[0].is_a?(Integer)) && args[1].is_a?(Hash)
79
+ time, record = args
80
+ feed_to_plugin(@default_tag, OneEventStream.new(time, record))
81
+ else
82
+ raise ArgumentError, "unexpected values of argument: #{args[0].class}, #{args[1].class}"
83
+ end
84
+ when 3
85
+ tag, time, record = args
86
+ if tag.is_a?(String) && (time.is_a?(Fluent::EventTime) || time.is_a?(Integer)) && record.is_a?(Hash)
87
+ feed_to_plugin(tag, OneEventStream.new(time, record))
88
+ else
89
+ raise ArgumentError, "unexpected values of argument: #{tag.class}, #{time.class}, #{record.class}"
90
+ end
91
+ else
92
+ raise ArgumentError, "unexpected number of arguments: #{args}"
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end