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
@@ -0,0 +1,175 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin_helper/compat_parameters'
3
+ require 'fluent/plugin/base'
4
+
5
+ class CompatParameterTest < Test::Unit::TestCase
6
+ setup do
7
+ Fluent::Test.setup
8
+ @i = nil
9
+ end
10
+
11
+ teardown do
12
+ if @i
13
+ @i.stop unless @i.stopped?
14
+ @i.before_shutdown unless @i.before_shutdown?
15
+ @i.shutdown unless @i.shutdown?
16
+ @i.after_shutdown unless @i.after_shutdown?
17
+ @i.close unless @i.closed?
18
+ @i.terminate unless @i.terminated?
19
+ end
20
+ end
21
+
22
+ class Dummy0 < Fluent::Plugin::Output
23
+ helpers :compat_parameters
24
+ def compat_parameters_default_chunk_key
25
+ ''
26
+ end
27
+ def write(chunk)
28
+ # dummy
29
+ end
30
+ end
31
+ class Dummy1 < Fluent::Plugin::Output
32
+ helpers :compat_parameters
33
+ def compat_parameters_default_chunk_key
34
+ 'time'
35
+ end
36
+ def write(chunk)
37
+ # dummy
38
+ end
39
+ end
40
+ class Dummy2 < Fluent::Plugin::Output
41
+ helpers :compat_parameters
42
+ # for test to assume default key time by 'time_slice_format'
43
+ def write(chunk)
44
+ # dummy
45
+ end
46
+ end
47
+ class Dummy3 < Fluent::Plugin::Output
48
+ helpers :compat_parameters
49
+ def compat_parameters_default_chunk_key
50
+ 'tag'
51
+ end
52
+ def write(chunk)
53
+ # dummy
54
+ end
55
+ end
56
+
57
+ sub_test_case 'plugins which does not have default chunk key' do
58
+ setup do
59
+ @p = Dummy0
60
+ end
61
+
62
+ test 'plugin helper converts parameters into plugin configuration parameters' do
63
+ hash = {
64
+ 'num_threads' => 8,
65
+ 'flush_interval' => '10s',
66
+ 'buffer_chunk_limit' => '8m',
67
+ 'buffer_queue_limit' => '1024',
68
+ 'flush_at_shutdown' => 'yes',
69
+ }
70
+ conf = config_element('ROOT', '', hash)
71
+ @i = @p.new
72
+ @i.configure(conf)
73
+
74
+ assert_equal 'memory', @i.buffer_config[:@type]
75
+ assert_equal [], @i.buffer_config.chunk_keys
76
+ assert_equal 8, @i.buffer_config.flush_thread_count
77
+ assert_equal 10, @i.buffer_config.flush_interval
78
+ assert @i.buffer_config.flush_at_shutdown
79
+
80
+ assert_equal 8*1024*1024, @i.buffer.chunk_limit_size
81
+ assert_equal 1024, @i.buffer.queue_length_limit
82
+ end
83
+ end
84
+
85
+ sub_test_case 'plugins which has default chunk key: time' do
86
+ setup do
87
+ @p = Dummy1
88
+ end
89
+
90
+ test 'plugin helper converts parameters into plugin configuration parameters' do
91
+ hash = {
92
+ 'buffer_type' => 'file',
93
+ 'buffer_path' => '/tmp/mybuffer',
94
+ 'disable_retry_limit' => 'yes',
95
+ 'max_retry_wait' => '1h',
96
+ 'buffer_queue_full_action' => 'block',
97
+ }
98
+ conf = config_element('ROOT', '', hash)
99
+ @i = @p.new
100
+ @i.configure(conf)
101
+
102
+ assert_equal 'file', @i.buffer_config[:@type]
103
+ assert_equal 24*60*60, @i.buffer_config.timekey
104
+ assert @i.buffer_config.retry_forever
105
+ assert_equal 60*60, @i.buffer_config.retry_max_interval
106
+ assert_equal :block, @i.buffer_config.overflow_action
107
+
108
+ assert !@i.chunk_key_tag
109
+ assert_equal [], @i.chunk_keys
110
+
111
+ assert_equal '/tmp/mybuffer/buffer.*.log', @i.buffer.path
112
+ end
113
+ end
114
+
115
+ sub_test_case 'plugins which does not have default chunk key' do
116
+ setup do
117
+ @p = Dummy2
118
+ end
119
+
120
+ test 'plugin helper converts parameters into plugin configuration parameters' do
121
+ hash = {
122
+ 'buffer_type' => 'file',
123
+ 'buffer_path' => '/tmp/mybuffer',
124
+ 'time_slice_format' => '%Y%m%d%H',
125
+ 'time_slice_wait' => '10',
126
+ 'retry_limit' => '1024',
127
+ 'buffer_queue_full_action' => 'drop_oldest_chunk',
128
+ }
129
+ conf = config_element('ROOT', '', hash)
130
+ @i = @p.new
131
+ @i.configure(conf)
132
+
133
+ assert_equal 'file', @i.buffer_config[:@type]
134
+ assert_equal 60*60, @i.buffer_config.timekey
135
+ assert_equal 10, @i.buffer_config.timekey_wait
136
+ assert_equal 1024, @i.buffer_config.retry_max_times
137
+ assert_equal :drop_oldest_chunk, @i.buffer_config.overflow_action
138
+
139
+ assert @i.chunk_key_time
140
+ assert !@i.chunk_key_tag
141
+ assert_equal [], @i.chunk_keys
142
+
143
+ assert_equal '/tmp/mybuffer/buffer.*.log', @i.buffer.path
144
+ end
145
+ end
146
+
147
+ sub_test_case 'plugins which has default chunk key: tag' do
148
+ setup do
149
+ @p = Dummy3
150
+ end
151
+
152
+ test 'plugin helper converts parameters into plugin configuration parameters' do
153
+ hash = {
154
+ 'buffer_type' => 'memory',
155
+ 'num_threads' => '10',
156
+ 'flush_interval' => '10s',
157
+ 'try_flush_interval' => '0.1',
158
+ 'queued_chunk_flush_interval' => '0.5',
159
+ }
160
+ conf = config_element('ROOT', '', hash)
161
+ @i = @p.new
162
+ @i.configure(conf)
163
+
164
+ assert_equal 'memory', @i.buffer_config[:@type]
165
+ assert_equal 10, @i.buffer_config.flush_thread_count
166
+ assert_equal 10, @i.buffer_config.flush_interval
167
+ assert_equal 0.1, @i.buffer_config.flush_thread_interval
168
+ assert_equal 0.5, @i.buffer_config.flush_thread_burst_interval
169
+
170
+ assert !@i.chunk_key_time
171
+ assert @i.chunk_key_tag
172
+ assert_equal [], @i.chunk_keys
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,51 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin_helper/event_emitter'
3
+ require 'fluent/plugin/base'
4
+
5
+ class EventEmitterTest < Test::Unit::TestCase
6
+ setup do
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ class Dummy0 < Fluent::Plugin::TestBase
11
+ end
12
+
13
+ class Dummy < Fluent::Plugin::TestBase
14
+ helpers :event_emitter
15
+ end
16
+
17
+ test 'can be instantiated to be able to emit with router' do
18
+ d0 = Dummy0.new
19
+ assert d0.respond_to?(:has_router?)
20
+ assert !d0.has_router?
21
+ assert !d0.respond_to?(:router)
22
+
23
+ d1 = Dummy.new
24
+ assert d1.respond_to?(:has_router?)
25
+ assert d1.has_router?
26
+ assert d1.respond_to?(:router)
27
+ d1.stop; d1.shutdown; d1.close; d1.terminate
28
+ end
29
+
30
+ test 'can be configured with valid router' do
31
+ d1 = Dummy.new
32
+ assert d1.has_router?
33
+ assert_nil d1.router
34
+
35
+ assert_nothing_raised do
36
+ d1.configure(config_element())
37
+ end
38
+
39
+ assert d1.router
40
+
41
+ d1.shutdown
42
+
43
+ assert d1.router
44
+
45
+ d1.close
46
+
47
+ assert_nil d1.router
48
+
49
+ d1.terminate
50
+ end
51
+ end
@@ -0,0 +1,52 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin_helper/event_loop'
3
+ require 'fluent/plugin/base'
4
+
5
+ class EventLoopTest < Test::Unit::TestCase
6
+ class Dummy < Fluent::Plugin::TestBase
7
+ helpers :event_loop
8
+ def configure(conf)
9
+ super
10
+ @_event_loop_run_timeout = 0.1
11
+ end
12
+ end
13
+
14
+ test 'can be instantiated to be able to create event loop' do
15
+ d1 = Dummy.new
16
+ assert d1.respond_to?(:event_loop_attach)
17
+ assert d1.respond_to?(:event_loop_running?)
18
+ assert d1.respond_to?(:_event_loop)
19
+ assert d1._event_loop
20
+ assert !d1.event_loop_running?
21
+ end
22
+
23
+ test 'can be configured' do
24
+ d1 = Dummy.new
25
+ assert_nothing_raised do
26
+ d1.configure(config_element())
27
+ end
28
+ assert d1.plugin_id
29
+ assert d1.log
30
+ end
31
+
32
+ test 'can run event loop by start, stop by shutdown/close and clear by terminate' do
33
+ d1 = Dummy.new
34
+ d1.configure(config_element())
35
+ assert !d1.event_loop_running?
36
+
37
+ d1.start
38
+ d1.event_loop_wait_until_start
39
+
40
+ assert d1.event_loop_running?
41
+ assert_equal 1, d1._event_loop.watchers.size
42
+
43
+ d1.shutdown
44
+ d1.close
45
+
46
+ assert !d1.event_loop_running?
47
+
48
+ d1.terminate
49
+
50
+ assert_nil d1._event_loop
51
+ end
52
+ end
@@ -0,0 +1,399 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin_helper/retry_state'
3
+ require 'fluent/plugin/base'
4
+
5
+ require 'time'
6
+
7
+ class Fluent::PluginHelper::RetryState::RetryStateMachine
8
+ def override_current_time(time)
9
+ (class << self; self; end).module_eval do
10
+ alias_method(:current_time_orig, :current_time)
11
+ define_method(:current_time){ time }
12
+ end
13
+ end
14
+ end
15
+
16
+ class RetryStateHelperTest < Test::Unit::TestCase
17
+ class Dummy < Fluent::Plugin::TestBase
18
+ helpers :retry_state
19
+ end
20
+
21
+ setup do
22
+ @d = Dummy.new
23
+ end
24
+
25
+ test 'randomize can generate value within specified +/- range' do
26
+ s = @d.retry_state_create(:t1, :exponential_backoff, 0.1, 30) # default enabled w/ 0.125
27
+ 500.times do
28
+ r = s.randomize(1000)
29
+ assert{ r >= 875 && r < 1125 }
30
+ end
31
+
32
+ s = @d.retry_state_create(:t1, :exponential_backoff, 0.1, 30, randomize_width: 0.25)
33
+ 500.times do
34
+ r = s.randomize(1000)
35
+ assert{ r >= 750 && r < 1250 }
36
+ end
37
+ end
38
+
39
+ test 'plugin can create retry_state machine' do
40
+ s = @d.retry_state_create(:t1, :exponential_backoff, 0.1, 30)
41
+ # attr_reader :title, :start, :steps, :next_time, :timeout_at, :current, :secondary_transition_at, :secondary_transition_times
42
+
43
+ assert_equal :t1, s.title
44
+ start_time = s.start
45
+
46
+ assert_equal 0, s.steps
47
+ assert_equal (start_time + 0.1).to_i, s.next_time.to_i
48
+ assert_equal (start_time + 0.1).nsec, s.next_time.nsec
49
+ assert_equal (start_time + 30), s.timeout_at
50
+
51
+ assert_equal :primary, s.current
52
+ assert{ s.is_a? Fluent::PluginHelper::RetryState::ExponentialBackOffRetry }
53
+ end
54
+
55
+ test 'periodic retries' do
56
+ s = @d.retry_state_create(:t2, :periodic, 3, 29, randomize: false)
57
+ dummy_current_time = s.start
58
+ s.override_current_time(dummy_current_time)
59
+
60
+ assert_equal dummy_current_time, s.current_time
61
+ assert_equal (dummy_current_time + 29), s.timeout_at
62
+ assert_equal (dummy_current_time + 3), s.next_time
63
+
64
+ i = 1
65
+ while i < 9
66
+ s.override_current_time(s.next_time)
67
+ s.step
68
+ assert_equal i, s.steps
69
+ assert_equal (s.current_time + 3), s.next_time
70
+ assert !s.limit?
71
+ i += 1
72
+ end
73
+
74
+ assert_equal 9, i
75
+ s.override_current_time(s.next_time)
76
+ s.step
77
+ assert_equal s.timeout_at, s.next_time
78
+ assert s.limit?
79
+ end
80
+
81
+ test 'periodic retries with max_steps' do
82
+ s = @d.retry_state_create(:t2, :periodic, 3, 29, randomize: false, max_steps: 5)
83
+ dummy_current_time = s.start
84
+ s.override_current_time(dummy_current_time)
85
+
86
+ assert_equal dummy_current_time, s.current_time
87
+ assert_equal (dummy_current_time + 29), s.timeout_at
88
+ assert_equal (dummy_current_time + 3), s.next_time
89
+
90
+ i = 1
91
+ while i < 5
92
+ s.override_current_time(s.next_time)
93
+ s.step
94
+ assert_equal i, s.steps
95
+ assert_equal (s.current_time + 3), s.next_time
96
+ assert !s.limit?
97
+ i += 1
98
+ end
99
+
100
+ assert_equal 5, i
101
+ s.override_current_time(s.next_time)
102
+ s.step
103
+ assert_equal (s.current_time + 3), s.next_time
104
+ assert s.limit?
105
+ end
106
+
107
+ test 'periodic retries with secondary' do
108
+ s = @d.retry_state_create(:t3, :periodic, 3, 100, randomize: false, secondary: true) # threshold 0.8
109
+ dummy_current_time = s.start
110
+ s.override_current_time(dummy_current_time)
111
+
112
+ assert_equal dummy_current_time, s.current_time
113
+ assert_equal (dummy_current_time + 100), s.timeout_at
114
+ assert_equal (dummy_current_time + 100 * 0.8), s.secondary_transition_at
115
+
116
+ assert_equal (dummy_current_time + 3), s.next_time
117
+ assert !s.secondary?
118
+
119
+ i = 1
120
+ while i < 26
121
+ s.override_current_time(s.next_time)
122
+ assert !s.secondary?
123
+
124
+ s.step
125
+ assert_equal i, s.steps
126
+ assert_equal (s.current_time + 3), s.next_time
127
+ assert !s.limit?
128
+ i += 1
129
+ end
130
+
131
+ assert_equal 26, i
132
+ s.override_current_time(s.next_time) # 78
133
+ assert !s.secondary?
134
+
135
+ s.step
136
+ assert_equal 26, s.steps
137
+ assert_equal s.secondary_transition_at, s.next_time
138
+ assert !s.limit?
139
+
140
+ i += 1
141
+ assert_equal 27, i
142
+ s.override_current_time(s.next_time) # 80
143
+ assert s.secondary?
144
+
145
+ s.step
146
+ assert_equal (s.current_time + 3), s.next_time
147
+ assert_equal s.steps, s.secondary_transition_steps
148
+ assert !s.limit?
149
+
150
+ i += 1
151
+
152
+ while i < 33
153
+ s.override_current_time(s.next_time)
154
+ assert s.secondary?
155
+
156
+ s.step
157
+ assert_equal (s.current_time + 3), s.next_time
158
+ assert !s.limit?
159
+ i += 1
160
+ end
161
+
162
+ assert_equal 33, i
163
+ s.override_current_time(s.next_time) # 98
164
+ assert s.secondary?
165
+
166
+ s.step
167
+ assert_equal s.timeout_at, s.next_time
168
+ assert s.limit?
169
+ end
170
+
171
+ test 'periodic retries with secondary and specified threshold' do
172
+ s = @d.retry_state_create(:t3, :periodic, 3, 100, randomize: false, secondary: true, secondary_threshold: 0.75)
173
+ dummy_current_time = s.start
174
+ s.override_current_time(dummy_current_time)
175
+
176
+ assert_equal dummy_current_time, s.current_time
177
+ assert_equal (dummy_current_time + 100), s.timeout_at
178
+ assert_equal (dummy_current_time + 100 * 0.75), s.secondary_transition_at
179
+ end
180
+
181
+ test 'exponential backoff forever without randomization' do
182
+ s = @d.retry_state_create(:t11, :exponential_backoff, 0.1, 300, randomize: false, forever: true, backoff_base: 2)
183
+ dummy_current_time = s.start
184
+ s.override_current_time(dummy_current_time)
185
+
186
+ assert_equal dummy_current_time, s.current_time
187
+
188
+ assert_equal 0, s.steps
189
+ assert_equal (dummy_current_time + 0.1), s.next_time
190
+
191
+ i = 1
192
+ while i < 300
193
+ s.step
194
+ assert_equal i, s.steps
195
+ assert_equal (dummy_current_time + 0.1 * (2 ** (i - 1))), s.next_time
196
+ assert !s.limit?
197
+ i += 1
198
+ end
199
+ end
200
+
201
+ test 'exponential backoff with max_interval' do
202
+ s = @d.retry_state_create(:t12, :exponential_backoff, 0.1, 300, randomize: false, forever: true, backoff_base: 2, max_interval: 100)
203
+ dummy_current_time = s.start
204
+ s.override_current_time(dummy_current_time)
205
+
206
+ assert_equal dummy_current_time, s.current_time
207
+
208
+ assert_equal 0, s.steps
209
+ assert_equal (dummy_current_time + 0.1), s.next_time
210
+
211
+ # 0.1 * (2 ** (10 - 1)) == 0.1 * 2 ** 9 == 51.2
212
+ # 0.1 * (2 ** (11 - 1)) == 0.1 * 2 ** 10 == 102.4
213
+ i = 1
214
+ while i < 11
215
+ s.step
216
+ assert_equal i, s.steps
217
+ assert_equal (dummy_current_time + 0.1 * (2 ** (i - 1))), s.next_time, "start:#{dummy_current_time}, i:#{i}"
218
+ i += 1
219
+ end
220
+
221
+ s.step
222
+ assert_equal 11, s.steps
223
+ assert_equal (dummy_current_time + 100), s.next_time
224
+
225
+ s.step
226
+ assert_equal 12, s.steps
227
+ assert_equal (dummy_current_time + 100), s.next_time
228
+ end
229
+
230
+ test 'exponential backoff with shorter timeout' do
231
+ s = @d.retry_state_create(:t13, :exponential_backoff, 1, 12, randomize: false, backoff_base: 2, max_interval: 10)
232
+ dummy_current_time = s.start
233
+ s.override_current_time(dummy_current_time)
234
+
235
+ assert_equal dummy_current_time, s.current_time
236
+
237
+ assert_equal (dummy_current_time + 12), s.timeout_at
238
+
239
+ assert_equal 0, s.steps
240
+ assert_equal (dummy_current_time + 1), s.next_time
241
+
242
+ # 1 + 1 + 2 + 4 (=8)
243
+
244
+ s.override_current_time(s.next_time)
245
+ s.step
246
+ assert_equal 1, s.steps
247
+ assert_equal (s.current_time + 1), s.next_time
248
+
249
+ s.override_current_time(s.next_time)
250
+ s.step
251
+ assert_equal 2, s.steps
252
+ assert_equal (s.current_time + 2), s.next_time
253
+
254
+ s.override_current_time(s.next_time)
255
+ s.step
256
+ assert_equal 3, s.steps
257
+ assert_equal (s.current_time + 4), s.next_time
258
+
259
+ assert !s.limit?
260
+
261
+ # + 8 (=16) > 12
262
+
263
+ s.override_current_time(s.next_time)
264
+ s.step
265
+ assert_equal 4, s.steps
266
+ assert_equal s.timeout_at, s.next_time
267
+
268
+ assert s.limit?
269
+ end
270
+
271
+ test 'exponential backoff with max_steps' do
272
+ s = @d.retry_state_create(:t14, :exponential_backoff, 1, 120, randomize: false, backoff_base: 2, max_interval: 10, max_steps: 6)
273
+ dummy_current_time = s.start
274
+ s.override_current_time(dummy_current_time)
275
+
276
+ assert_equal dummy_current_time, s.current_time
277
+
278
+ assert_equal (dummy_current_time + 120), s.timeout_at
279
+
280
+ assert_equal 0, s.steps
281
+ assert_equal (dummy_current_time + 1), s.next_time
282
+
283
+ s.override_current_time(s.next_time)
284
+ s.step
285
+ assert_equal 1, s.steps
286
+ assert_equal (s.current_time + 1), s.next_time
287
+
288
+ s.override_current_time(s.next_time)
289
+ s.step
290
+ assert_equal 2, s.steps
291
+ assert_equal (s.current_time + 2), s.next_time
292
+
293
+ s.override_current_time(s.next_time)
294
+ s.step
295
+ assert_equal 3, s.steps
296
+ assert_equal (s.current_time + 4), s.next_time
297
+
298
+ assert !s.limit?
299
+
300
+ s.override_current_time(s.next_time)
301
+ s.step
302
+ assert_equal 4, s.steps
303
+ assert_equal (s.current_time + 8), s.next_time
304
+
305
+ assert !s.limit?
306
+
307
+ s.override_current_time(s.next_time)
308
+ s.step
309
+ assert_equal 5, s.steps
310
+ assert_equal (s.current_time + 10), s.next_time
311
+
312
+ assert !s.limit?
313
+
314
+ s.override_current_time(s.next_time)
315
+ s.step
316
+ assert_equal 6, s.steps
317
+ assert_equal (s.current_time + 10), s.next_time
318
+
319
+ assert s.limit?
320
+ end
321
+
322
+ test 'exponential backoff retries with secondary' do
323
+ s = @d.retry_state_create(:t15, :exponential_backoff, 1, 100, randomize: false, backoff_base: 2, secondary: true) # threshold 0.8
324
+ dummy_current_time = s.start
325
+ s.override_current_time(dummy_current_time)
326
+
327
+ assert_equal dummy_current_time, s.current_time
328
+ assert_equal (dummy_current_time + 100), s.timeout_at
329
+ assert_equal (dummy_current_time + 100 * 0.8), s.secondary_transition_at
330
+
331
+ assert_equal (dummy_current_time + 1), s.next_time
332
+ assert !s.secondary?
333
+
334
+ # 1, 1(2), 2(4), 4(8), 8(16), 16(32), 32(64), (80), (81), (83), (87), (95), (100)
335
+ i = 1
336
+ while i < 7
337
+ s.override_current_time(s.next_time)
338
+ assert !s.secondary?
339
+
340
+ s.step
341
+ assert_equal i, s.steps
342
+ assert_equal (s.current_time + 1 * (2 ** (i - 1))), s.next_time
343
+ assert !s.limit?
344
+ i += 1
345
+ end
346
+
347
+ assert_equal 7, i
348
+ s.override_current_time(s.next_time) # 64
349
+ assert !s.secondary?
350
+
351
+ s.step
352
+ assert_equal 7, s.steps
353
+ assert_equal s.secondary_transition_at, s.next_time
354
+ assert !s.limit?
355
+
356
+ i += 1
357
+ assert_equal 8, i
358
+ s.override_current_time(s.next_time) # 80
359
+ assert s.secondary?
360
+
361
+ s.step
362
+ assert_equal 8, s.steps
363
+ assert_equal s.steps, s.secondary_transition_steps
364
+ assert_equal (s.secondary_transition_at + 1.0), s.next_time
365
+ assert !s.limit?
366
+
367
+ # 81, 82, 84, 88, 96, 100
368
+ j = 1
369
+ while j < 4
370
+ s.override_current_time(s.next_time)
371
+ assert s.secondary?
372
+ assert_equal :secondary, s.current
373
+
374
+ s.step
375
+ assert_equal (8 + j), s.steps
376
+ assert_equal (s.current_time + (1 * (2 ** j))), s.next_time
377
+ assert !s.limit?, "j:#{j}"
378
+ j += 1
379
+ end
380
+
381
+ assert_equal 4, j
382
+ s.override_current_time(s.next_time) # 96
383
+ assert s.secondary?
384
+
385
+ s.step
386
+ assert_equal s.timeout_at, s.next_time
387
+ assert s.limit?
388
+ end
389
+
390
+ test 'exponential backoff retries with secondary and specified threshold' do
391
+ s = @d.retry_state_create(:t16, :exponential_backoff, 1, 100, randomize: false, secondary: true, backoff_base: 2, secondary_threshold: 0.75)
392
+ dummy_current_time = s.start
393
+ s.override_current_time(dummy_current_time)
394
+
395
+ assert_equal dummy_current_time, s.current_time
396
+ assert_equal (dummy_current_time + 100), s.timeout_at
397
+ assert_equal (dummy_current_time + 100 * 0.75), s.secondary_transition_at
398
+ end
399
+ end