fluentd 0.14.4-x64-mingw32

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 (328) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE.md +6 -0
  3. data/.gitignore +26 -0
  4. data/.travis.yml +45 -0
  5. data/AUTHORS +2 -0
  6. data/CONTRIBUTING.md +35 -0
  7. data/COPYING +14 -0
  8. data/ChangeLog +276 -0
  9. data/Gemfile +9 -0
  10. data/README.md +51 -0
  11. data/Rakefile +53 -0
  12. data/Vagrantfile +17 -0
  13. data/appveyor.yml +41 -0
  14. data/bin/fluent-debug +5 -0
  15. data/example/copy_roundrobin.conf +39 -0
  16. data/example/filter_stdout.conf +22 -0
  17. data/example/in_forward.conf +11 -0
  18. data/example/in_http.conf +14 -0
  19. data/example/in_out_forward.conf +17 -0
  20. data/example/in_syslog.conf +15 -0
  21. data/example/in_tail.conf +14 -0
  22. data/example/in_tcp.conf +13 -0
  23. data/example/in_udp.conf +13 -0
  24. data/example/multi_filters.conf +61 -0
  25. data/example/out_buffered_null.conf +32 -0
  26. data/example/out_copy.conf +20 -0
  27. data/example/out_file.conf +13 -0
  28. data/example/out_forward.conf +35 -0
  29. data/example/out_forward_buf_file.conf +23 -0
  30. data/example/v0_12_filter.conf +78 -0
  31. data/example/v1_literal_example.conf +36 -0
  32. data/fluent.conf +139 -0
  33. data/fluentd.gemspec +51 -0
  34. data/lib/fluent/agent.rb +194 -0
  35. data/lib/fluent/command/bundler_injection.rb +45 -0
  36. data/lib/fluent/command/cat.rb +319 -0
  37. data/lib/fluent/command/debug.rb +102 -0
  38. data/lib/fluent/command/fluentd.rb +273 -0
  39. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  40. data/lib/fluent/compat/exec_util.rb +129 -0
  41. data/lib/fluent/compat/file_util.rb +54 -0
  42. data/lib/fluent/compat/filter.rb +68 -0
  43. data/lib/fluent/compat/formatter.rb +111 -0
  44. data/lib/fluent/compat/formatter_utils.rb +85 -0
  45. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  46. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  47. data/lib/fluent/compat/input.rb +49 -0
  48. data/lib/fluent/compat/output.rb +677 -0
  49. data/lib/fluent/compat/output_chain.rb +60 -0
  50. data/lib/fluent/compat/parser.rb +180 -0
  51. data/lib/fluent/compat/parser_utils.rb +40 -0
  52. data/lib/fluent/compat/propagate_default.rb +62 -0
  53. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  54. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  55. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  56. data/lib/fluent/compat/socket_util.rb +165 -0
  57. data/lib/fluent/compat/string_util.rb +34 -0
  58. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  59. data/lib/fluent/compat/type_converter.rb +90 -0
  60. data/lib/fluent/config.rb +56 -0
  61. data/lib/fluent/config/basic_parser.rb +123 -0
  62. data/lib/fluent/config/configure_proxy.rb +366 -0
  63. data/lib/fluent/config/dsl.rb +149 -0
  64. data/lib/fluent/config/element.rb +218 -0
  65. data/lib/fluent/config/error.rb +26 -0
  66. data/lib/fluent/config/literal_parser.rb +251 -0
  67. data/lib/fluent/config/parser.rb +107 -0
  68. data/lib/fluent/config/section.rb +212 -0
  69. data/lib/fluent/config/types.rb +136 -0
  70. data/lib/fluent/config/v1_parser.rb +190 -0
  71. data/lib/fluent/configurable.rb +176 -0
  72. data/lib/fluent/daemon.rb +15 -0
  73. data/lib/fluent/engine.rb +220 -0
  74. data/lib/fluent/env.rb +27 -0
  75. data/lib/fluent/event.rb +287 -0
  76. data/lib/fluent/event_router.rb +259 -0
  77. data/lib/fluent/filter.rb +21 -0
  78. data/lib/fluent/formatter.rb +23 -0
  79. data/lib/fluent/input.rb +21 -0
  80. data/lib/fluent/label.rb +38 -0
  81. data/lib/fluent/load.rb +36 -0
  82. data/lib/fluent/log.rb +445 -0
  83. data/lib/fluent/match.rb +141 -0
  84. data/lib/fluent/mixin.rb +31 -0
  85. data/lib/fluent/msgpack_factory.rb +62 -0
  86. data/lib/fluent/output.rb +26 -0
  87. data/lib/fluent/output_chain.rb +23 -0
  88. data/lib/fluent/parser.rb +23 -0
  89. data/lib/fluent/plugin.rb +161 -0
  90. data/lib/fluent/plugin/bare_output.rb +63 -0
  91. data/lib/fluent/plugin/base.rb +130 -0
  92. data/lib/fluent/plugin/buf_file.rb +154 -0
  93. data/lib/fluent/plugin/buf_memory.rb +34 -0
  94. data/lib/fluent/plugin/buffer.rb +603 -0
  95. data/lib/fluent/plugin/buffer/chunk.rb +160 -0
  96. data/lib/fluent/plugin/buffer/file_chunk.rb +323 -0
  97. data/lib/fluent/plugin/buffer/memory_chunk.rb +90 -0
  98. data/lib/fluent/plugin/exec_util.rb +22 -0
  99. data/lib/fluent/plugin/file_util.rb +22 -0
  100. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  101. data/lib/fluent/plugin/filter.rb +93 -0
  102. data/lib/fluent/plugin/filter_grep.rb +75 -0
  103. data/lib/fluent/plugin/filter_record_transformer.rb +342 -0
  104. data/lib/fluent/plugin/filter_stdout.rb +53 -0
  105. data/lib/fluent/plugin/formatter.rb +45 -0
  106. data/lib/fluent/plugin/formatter_csv.rb +47 -0
  107. data/lib/fluent/plugin/formatter_hash.rb +29 -0
  108. data/lib/fluent/plugin/formatter_json.rb +44 -0
  109. data/lib/fluent/plugin/formatter_ltsv.rb +41 -0
  110. data/lib/fluent/plugin/formatter_msgpack.rb +29 -0
  111. data/lib/fluent/plugin/formatter_out_file.rb +78 -0
  112. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  113. data/lib/fluent/plugin/formatter_stdout.rb +74 -0
  114. data/lib/fluent/plugin/in_debug_agent.rb +64 -0
  115. data/lib/fluent/plugin/in_dummy.rb +135 -0
  116. data/lib/fluent/plugin/in_exec.rb +149 -0
  117. data/lib/fluent/plugin/in_forward.rb +366 -0
  118. data/lib/fluent/plugin/in_gc_stat.rb +52 -0
  119. data/lib/fluent/plugin/in_http.rb +422 -0
  120. data/lib/fluent/plugin/in_monitor_agent.rb +401 -0
  121. data/lib/fluent/plugin/in_object_space.rb +90 -0
  122. data/lib/fluent/plugin/in_syslog.rb +204 -0
  123. data/lib/fluent/plugin/in_tail.rb +838 -0
  124. data/lib/fluent/plugin/in_tcp.rb +41 -0
  125. data/lib/fluent/plugin/in_udp.rb +37 -0
  126. data/lib/fluent/plugin/in_unix.rb +201 -0
  127. data/lib/fluent/plugin/input.rb +33 -0
  128. data/lib/fluent/plugin/multi_output.rb +95 -0
  129. data/lib/fluent/plugin/out_buffered_null.rb +59 -0
  130. data/lib/fluent/plugin/out_buffered_stdout.rb +70 -0
  131. data/lib/fluent/plugin/out_copy.rb +42 -0
  132. data/lib/fluent/plugin/out_exec.rb +114 -0
  133. data/lib/fluent/plugin/out_exec_filter.rb +393 -0
  134. data/lib/fluent/plugin/out_file.rb +167 -0
  135. data/lib/fluent/plugin/out_forward.rb +646 -0
  136. data/lib/fluent/plugin/out_null.rb +27 -0
  137. data/lib/fluent/plugin/out_relabel.rb +28 -0
  138. data/lib/fluent/plugin/out_roundrobin.rb +80 -0
  139. data/lib/fluent/plugin/out_stdout.rb +48 -0
  140. data/lib/fluent/plugin/out_stream.rb +130 -0
  141. data/lib/fluent/plugin/output.rb +1020 -0
  142. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  143. data/lib/fluent/plugin/parser.rb +175 -0
  144. data/lib/fluent/plugin/parser_apache.rb +28 -0
  145. data/lib/fluent/plugin/parser_apache2.rb +84 -0
  146. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  147. data/lib/fluent/plugin/parser_csv.rb +33 -0
  148. data/lib/fluent/plugin/parser_json.rb +79 -0
  149. data/lib/fluent/plugin/parser_ltsv.rb +50 -0
  150. data/lib/fluent/plugin/parser_multiline.rb +104 -0
  151. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  152. data/lib/fluent/plugin/parser_none.rb +36 -0
  153. data/lib/fluent/plugin/parser_regexp.rb +73 -0
  154. data/lib/fluent/plugin/parser_syslog.rb +82 -0
  155. data/lib/fluent/plugin/parser_tsv.rb +37 -0
  156. data/lib/fluent/plugin/socket_util.rb +22 -0
  157. data/lib/fluent/plugin/storage.rb +84 -0
  158. data/lib/fluent/plugin/storage_local.rb +132 -0
  159. data/lib/fluent/plugin/string_util.rb +22 -0
  160. data/lib/fluent/plugin_helper.rb +42 -0
  161. data/lib/fluent/plugin_helper/child_process.rb +298 -0
  162. data/lib/fluent/plugin_helper/compat_parameters.rb +224 -0
  163. data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
  164. data/lib/fluent/plugin_helper/event_loop.rb +118 -0
  165. data/lib/fluent/plugin_helper/formatter.rb +149 -0
  166. data/lib/fluent/plugin_helper/inject.rb +125 -0
  167. data/lib/fluent/plugin_helper/parser.rb +147 -0
  168. data/lib/fluent/plugin_helper/retry_state.rb +177 -0
  169. data/lib/fluent/plugin_helper/storage.rb +331 -0
  170. data/lib/fluent/plugin_helper/thread.rb +147 -0
  171. data/lib/fluent/plugin_helper/timer.rb +90 -0
  172. data/lib/fluent/plugin_id.rb +63 -0
  173. data/lib/fluent/process.rb +504 -0
  174. data/lib/fluent/registry.rb +99 -0
  175. data/lib/fluent/root_agent.rb +314 -0
  176. data/lib/fluent/rpc.rb +94 -0
  177. data/lib/fluent/supervisor.rb +680 -0
  178. data/lib/fluent/system_config.rb +122 -0
  179. data/lib/fluent/test.rb +56 -0
  180. data/lib/fluent/test/base.rb +85 -0
  181. data/lib/fluent/test/driver/base.rb +179 -0
  182. data/lib/fluent/test/driver/base_owned.rb +70 -0
  183. data/lib/fluent/test/driver/base_owner.rb +125 -0
  184. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  185. data/lib/fluent/test/driver/filter.rb +57 -0
  186. data/lib/fluent/test/driver/formatter.rb +30 -0
  187. data/lib/fluent/test/driver/input.rb +31 -0
  188. data/lib/fluent/test/driver/multi_output.rb +52 -0
  189. data/lib/fluent/test/driver/output.rb +76 -0
  190. data/lib/fluent/test/driver/parser.rb +30 -0
  191. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  192. data/lib/fluent/test/filter_test.rb +77 -0
  193. data/lib/fluent/test/formatter_test.rb +65 -0
  194. data/lib/fluent/test/helpers.rb +79 -0
  195. data/lib/fluent/test/input_test.rb +172 -0
  196. data/lib/fluent/test/log.rb +73 -0
  197. data/lib/fluent/test/output_test.rb +156 -0
  198. data/lib/fluent/test/parser_test.rb +70 -0
  199. data/lib/fluent/time.rb +175 -0
  200. data/lib/fluent/timezone.rb +133 -0
  201. data/lib/fluent/unique_id.rb +39 -0
  202. data/lib/fluent/version.rb +21 -0
  203. data/lib/fluent/winsvc.rb +71 -0
  204. data/test/compat/test_calls_super.rb +166 -0
  205. data/test/compat/test_parser.rb +82 -0
  206. data/test/config/assertions.rb +42 -0
  207. data/test/config/test_config_parser.rb +507 -0
  208. data/test/config/test_configurable.rb +1194 -0
  209. data/test/config/test_configure_proxy.rb +386 -0
  210. data/test/config/test_dsl.rb +415 -0
  211. data/test/config/test_element.rb +403 -0
  212. data/test/config/test_literal_parser.rb +297 -0
  213. data/test/config/test_section.rb +184 -0
  214. data/test/config/test_system_config.rb +120 -0
  215. data/test/config/test_types.rb +171 -0
  216. data/test/helper.rb +119 -0
  217. data/test/plugin/data/2010/01/20100102-030405.log +0 -0
  218. data/test/plugin/data/2010/01/20100102-030406.log +0 -0
  219. data/test/plugin/data/2010/01/20100102.log +0 -0
  220. data/test/plugin/data/log/bar +0 -0
  221. data/test/plugin/data/log/foo/bar.log +0 -0
  222. data/test/plugin/data/log/test.log +0 -0
  223. data/test/plugin/test_bare_output.rb +118 -0
  224. data/test/plugin/test_base.rb +75 -0
  225. data/test/plugin/test_buf_file.rb +571 -0
  226. data/test/plugin/test_buf_memory.rb +42 -0
  227. data/test/plugin/test_buffer.rb +1200 -0
  228. data/test/plugin/test_buffer_chunk.rb +168 -0
  229. data/test/plugin/test_buffer_file_chunk.rb +771 -0
  230. data/test/plugin/test_buffer_memory_chunk.rb +265 -0
  231. data/test/plugin/test_file_util.rb +96 -0
  232. data/test/plugin/test_filter.rb +353 -0
  233. data/test/plugin/test_filter_grep.rb +119 -0
  234. data/test/plugin/test_filter_record_transformer.rb +600 -0
  235. data/test/plugin/test_filter_stdout.rb +211 -0
  236. data/test/plugin/test_formatter_csv.rb +94 -0
  237. data/test/plugin/test_formatter_json.rb +30 -0
  238. data/test/plugin/test_formatter_ltsv.rb +52 -0
  239. data/test/plugin/test_formatter_msgpack.rb +28 -0
  240. data/test/plugin/test_formatter_out_file.rb +95 -0
  241. data/test/plugin/test_formatter_single_value.rb +38 -0
  242. data/test/plugin/test_in_debug_agent.rb +28 -0
  243. data/test/plugin/test_in_dummy.rb +188 -0
  244. data/test/plugin/test_in_exec.rb +133 -0
  245. data/test/plugin/test_in_forward.rb +635 -0
  246. data/test/plugin/test_in_gc_stat.rb +39 -0
  247. data/test/plugin/test_in_http.rb +442 -0
  248. data/test/plugin/test_in_monitor_agent.rb +329 -0
  249. data/test/plugin/test_in_object_space.rb +64 -0
  250. data/test/plugin/test_in_syslog.rb +205 -0
  251. data/test/plugin/test_in_tail.rb +1001 -0
  252. data/test/plugin/test_in_tcp.rb +102 -0
  253. data/test/plugin/test_in_udp.rb +121 -0
  254. data/test/plugin/test_in_unix.rb +126 -0
  255. data/test/plugin/test_input.rb +122 -0
  256. data/test/plugin/test_multi_output.rb +180 -0
  257. data/test/plugin/test_out_buffered_null.rb +79 -0
  258. data/test/plugin/test_out_buffered_stdout.rb +122 -0
  259. data/test/plugin/test_out_copy.rb +160 -0
  260. data/test/plugin/test_out_exec.rb +155 -0
  261. data/test/plugin/test_out_exec_filter.rb +262 -0
  262. data/test/plugin/test_out_file.rb +383 -0
  263. data/test/plugin/test_out_forward.rb +590 -0
  264. data/test/plugin/test_out_null.rb +29 -0
  265. data/test/plugin/test_out_relabel.rb +28 -0
  266. data/test/plugin/test_out_roundrobin.rb +146 -0
  267. data/test/plugin/test_out_stdout.rb +92 -0
  268. data/test/plugin/test_out_stream.rb +93 -0
  269. data/test/plugin/test_output.rb +568 -0
  270. data/test/plugin/test_output_as_buffered.rb +1604 -0
  271. data/test/plugin/test_output_as_buffered_overflow.rb +250 -0
  272. data/test/plugin/test_output_as_buffered_retries.rb +839 -0
  273. data/test/plugin/test_output_as_buffered_secondary.rb +817 -0
  274. data/test/plugin/test_output_as_standard.rb +374 -0
  275. data/test/plugin/test_owned_by.rb +35 -0
  276. data/test/plugin/test_parser_apache.rb +42 -0
  277. data/test/plugin/test_parser_apache2.rb +38 -0
  278. data/test/plugin/test_parser_apache_error.rb +45 -0
  279. data/test/plugin/test_parser_base.rb +32 -0
  280. data/test/plugin/test_parser_csv.rb +104 -0
  281. data/test/plugin/test_parser_json.rb +107 -0
  282. data/test/plugin/test_parser_labeled_tsv.rb +129 -0
  283. data/test/plugin/test_parser_multiline.rb +100 -0
  284. data/test/plugin/test_parser_nginx.rb +48 -0
  285. data/test/plugin/test_parser_none.rb +53 -0
  286. data/test/plugin/test_parser_regexp.rb +277 -0
  287. data/test/plugin/test_parser_syslog.rb +66 -0
  288. data/test/plugin/test_parser_time.rb +46 -0
  289. data/test/plugin/test_parser_tsv.rb +121 -0
  290. data/test/plugin/test_storage.rb +167 -0
  291. data/test/plugin/test_storage_local.rb +8 -0
  292. data/test/plugin/test_string_util.rb +26 -0
  293. data/test/plugin_helper/test_child_process.rb +608 -0
  294. data/test/plugin_helper/test_compat_parameters.rb +242 -0
  295. data/test/plugin_helper/test_event_emitter.rb +51 -0
  296. data/test/plugin_helper/test_event_loop.rb +52 -0
  297. data/test/plugin_helper/test_formatter.rb +252 -0
  298. data/test/plugin_helper/test_inject.rb +487 -0
  299. data/test/plugin_helper/test_parser.rb +263 -0
  300. data/test/plugin_helper/test_retry_state.rb +399 -0
  301. data/test/plugin_helper/test_storage.rb +521 -0
  302. data/test/plugin_helper/test_thread.rb +164 -0
  303. data/test/plugin_helper/test_timer.rb +131 -0
  304. data/test/scripts/exec_script.rb +32 -0
  305. data/test/scripts/fluent/plugin/formatter_known.rb +8 -0
  306. data/test/scripts/fluent/plugin/out_test.rb +81 -0
  307. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  308. data/test/scripts/fluent/plugin/parser_known.rb +4 -0
  309. data/test/test_config.rb +179 -0
  310. data/test/test_configdsl.rb +148 -0
  311. data/test/test_event.rb +329 -0
  312. data/test/test_event_router.rb +331 -0
  313. data/test/test_event_time.rb +184 -0
  314. data/test/test_filter.rb +121 -0
  315. data/test/test_formatter.rb +319 -0
  316. data/test/test_input.rb +31 -0
  317. data/test/test_log.rb +572 -0
  318. data/test/test_match.rb +137 -0
  319. data/test/test_mixin.rb +351 -0
  320. data/test/test_output.rb +214 -0
  321. data/test/test_plugin_classes.rb +136 -0
  322. data/test/test_plugin_helper.rb +81 -0
  323. data/test/test_process.rb +48 -0
  324. data/test/test_root_agent.rb +278 -0
  325. data/test/test_supervisor.rb +339 -0
  326. data/test/test_time_formatter.rb +186 -0
  327. data/test/test_unique_id.rb +47 -0
  328. metadata +823 -0
@@ -0,0 +1,1194 @@
1
+ require_relative '../helper'
2
+ require 'fluent/configurable'
3
+ require 'fluent/config/element'
4
+ require 'fluent/config/section'
5
+
6
+ module ConfigurableSpec
7
+ class Base1
8
+ include Fluent::Configurable
9
+
10
+ config_param :node, :string, default: "node"
11
+ config_param :flag1, :bool, default: false
12
+ config_param :flag2, :bool, default: true
13
+
14
+ config_param :name1, :string
15
+ config_param :name2, :string
16
+ config_param :name3, :string, default: "base1"
17
+ config_param :name4, :string, default: "base1"
18
+
19
+ config_param :opt1, :enum, list: [:foo, :bar, :baz]
20
+ config_param :opt2, :enum, list: [:foo, :bar, :baz], default: :foo
21
+
22
+ def get_all
23
+ [@node, @flag1, @flag2, @name1, @name2, @name3, @name4]
24
+ end
25
+ end
26
+
27
+ class Base2 < Base1
28
+ config_set_default :name2, "base2"
29
+ config_set_default :name4, "base2"
30
+ config_set_default :opt1, :bar
31
+ config_param :name5, :string
32
+ config_param :name6, :string, default: "base2"
33
+ config_param :opt3, :enum, list: [:a, :b]
34
+
35
+ def get_all
36
+ ary = super
37
+ ary + [@name5, @name6]
38
+ end
39
+ end
40
+
41
+ class Base3 < Base2
42
+ config_set_default :opt3, :a
43
+ config_section :node do
44
+ config_param :name, :string, default: "node"
45
+ config_param :type, :string
46
+ end
47
+ config_section :branch, required: true, multi: true do
48
+ config_argument :name, :string
49
+ config_param :size, :integer, default: 10
50
+ config_section :leaf, required: false, multi: true do
51
+ config_param :weight, :integer
52
+ config_section :worm, param_name: 'worms', multi: true do
53
+ config_param :type, :string, default: 'ladybird'
54
+ end
55
+ end
56
+ end
57
+
58
+ def get_all
59
+ ary = super
60
+ ary + [@branch]
61
+ end
62
+ end
63
+
64
+ class Base4 < Base2
65
+ config_set_default :opt3, :a
66
+ config_section :node, param_name: :nodes do
67
+ config_argument :num, :integer
68
+ config_param :name, :string, default: "node"
69
+ config_param :type, :string, default: "b4"
70
+ end
71
+ config_section :description1, required: false, multi: false do
72
+ config_argument :note, :string, default: "desc1"
73
+ config_param :text, :string
74
+ end
75
+ config_section :description2, required: true, multi: false do
76
+ config_argument :note, :string, default: "desc2"
77
+ config_param :text, :string
78
+ end
79
+ config_section :description3, required: true, multi: true do
80
+ config_argument :note, default: "desc3" do |val|
81
+ "desc3: #{val}"
82
+ end
83
+ config_param :text, :string
84
+ end
85
+
86
+ def get_all
87
+ ary = super
88
+ ary + [@nodes, @description1, @description2, @description3]
89
+ end
90
+ end
91
+
92
+ class Init0
93
+ include Fluent::Configurable
94
+ config_section :sec1, init: true, multi: false do
95
+ config_param :name, :string, default: 'sec1'
96
+ end
97
+ config_section :sec2, init: true, multi: true do
98
+ config_param :name, :string, default: 'sec1'
99
+ end
100
+ end
101
+
102
+ class Example0
103
+ include Fluent::Configurable
104
+
105
+ config_param :stringvalue, :string
106
+ config_param :boolvalue, :bool
107
+ config_param :integervalue, :integer
108
+ config_param :sizevalue, :size
109
+ config_param :timevalue, :time
110
+ config_param :floatvalue, :float
111
+ config_param :hashvalue, :hash
112
+ config_param :arrayvalue, :array
113
+ end
114
+
115
+ class Example1
116
+ include Fluent::Configurable
117
+
118
+ config_param :name, :string, alias: :fullname
119
+ config_param :bool, :bool, alias: :flag
120
+ config_section :detail, required: false, multi: false, alias: "information" do
121
+ config_param :address, :string, default: "x"
122
+ end
123
+
124
+ def get_all
125
+ [@name, @detail]
126
+ end
127
+ end
128
+
129
+ class Example3
130
+ include Fluent::Configurable
131
+
132
+ config_param :age, :integer, default: 10
133
+
134
+ config_section :appendix, required: true, multi: false, final: true do
135
+ config_param :type, :string
136
+ config_param :name, :string, default: "x"
137
+ end
138
+
139
+ def get_all
140
+ [@name, @detail]
141
+ end
142
+ end
143
+
144
+ class Example5
145
+ include Fluent::Configurable
146
+
147
+ config_param :normal_param, :string
148
+ config_param :secret_param, :string, secret: true
149
+
150
+ config_section :section do
151
+ config_param :normal_param2, :string
152
+ config_param :secret_param2, :string, secret: true
153
+ end
154
+ end
155
+
156
+ class Example6
157
+ include Fluent::Configurable
158
+ config_param :obj1, :hash, default: {}
159
+ config_param :obj2, :array, default: []
160
+ end
161
+
162
+ module Overwrite
163
+ class Base
164
+ include Fluent::Configurable
165
+
166
+ config_param :name, :string, alias: :fullname
167
+ config_param :bool, :bool, alias: :flag
168
+ config_section :detail, required: false, multi: false, alias: "information" do
169
+ config_param :address, :string, default: "x"
170
+ end
171
+ end
172
+
173
+ class Required < Base
174
+ config_section :detail, required: true do
175
+ config_param :address, :string, default: "x"
176
+ end
177
+ end
178
+
179
+ class Multi < Base
180
+ config_section :detail, multi: true do
181
+ config_param :address, :string, default: "x"
182
+ end
183
+ end
184
+
185
+ class Alias < Base
186
+ config_section :detail, alias: "information2" do
187
+ config_param :address, :string, default: "x"
188
+ end
189
+ end
190
+
191
+ class DefaultOptions < Base
192
+ config_section :detail do
193
+ config_param :address, :string, default: "x"
194
+ end
195
+ end
196
+
197
+ class DetailAddressDefault < Base
198
+ config_section :detail do
199
+ config_param :address, :string, default: "y"
200
+ end
201
+ end
202
+
203
+ class AddParam < Base
204
+ config_section :detail do
205
+ config_param :phone_no, :string
206
+ end
207
+ end
208
+
209
+ class AddParamOverwriteAddress < Base
210
+ config_section :detail do
211
+ config_param :address, :string, default: "y"
212
+ config_param :phone_no, :string
213
+ end
214
+ end
215
+ end
216
+
217
+ module Final
218
+ # Show what is allowed in finalized sections
219
+ # InheritsFinalized < Finalized < Base
220
+ class Base
221
+ include Fluent::Configurable
222
+ config_section :appendix, multi: false, final: false do
223
+ config_param :code, :string
224
+ config_param :name, :string
225
+ config_param :address, :string, default: ""
226
+ end
227
+ end
228
+
229
+ class Finalized < Base
230
+ # to non-finalized section
231
+ # subclass can change type (code)
232
+ # add default value (name)
233
+ # change default value (address)
234
+ # add field (age)
235
+ config_section :appendix, final: true do
236
+ config_param :code, :integer
237
+ config_set_default :name, "y"
238
+ config_set_default :address, "-"
239
+ config_param :age, :integer, default: 10
240
+ end
241
+ end
242
+
243
+ class InheritsFinalized < Finalized
244
+ # to finalized section
245
+ # subclass can add default value (code)
246
+ # change default value (age)
247
+ # add field (phone_no)
248
+ config_section :appendix do
249
+ config_set_default :code, 2
250
+ config_set_default :age, 0
251
+ config_param :phone_no, :string
252
+ end
253
+ end
254
+
255
+ # Show what is allowed/prohibited for finalized sections
256
+ class FinalizedBase
257
+ include Fluent::Configurable
258
+ config_section :appendix, param_name: :apd, init: false, required: true, multi: false, alias: "options", final: true do
259
+ config_param :name, :string
260
+ end
261
+ end
262
+
263
+ class FinalizedBase2
264
+ include Fluent::Configurable
265
+ config_section :appendix, param_name: :apd, init: false, required: false, multi: false, alias: "options", final: true do
266
+ config_param :name, :string
267
+ end
268
+ end
269
+
270
+ # subclass can change init with adding default values
271
+ class OverwriteInit < FinalizedBase2
272
+ config_section :appendix, init: true do
273
+ config_set_default :name, "moris"
274
+ config_param :code, :integer, default: 0
275
+ end
276
+ end
277
+
278
+ # subclass cannot change type (name)
279
+ class Subclass < FinalizedBase
280
+ config_section :appendix do
281
+ config_param :name, :integer
282
+ end
283
+ end
284
+
285
+ # subclass cannot change param_name
286
+ class OverwriteParamName < FinalizedBase
287
+ config_section :appendix, param_name: :adx do
288
+ end
289
+ end
290
+
291
+ # subclass cannot change final (section)
292
+ class OverwriteFinal < FinalizedBase
293
+ config_section :appendix, final: false do
294
+ config_param :name, :integer
295
+ end
296
+ end
297
+
298
+ # subclass cannot change required
299
+ class OverwriteRequired < FinalizedBase
300
+ config_section :appendix, required: false do
301
+ end
302
+ end
303
+
304
+ # subclass cannot change multi
305
+ class OverwriteMulti < FinalizedBase
306
+ config_section :appendix, multi: true do
307
+ end
308
+ end
309
+
310
+ # subclass cannot change alias
311
+ class OverwriteAlias < FinalizedBase
312
+ config_section :appendix, alias: "options2" do
313
+ end
314
+ end
315
+ end
316
+
317
+ module OverwriteDefaults
318
+ class Owner
319
+ include Fluent::Configurable
320
+ config_set_default :key1, "V1"
321
+ config_section :buffer do
322
+ config_set_default :size_of_something, 1024
323
+ end
324
+ end
325
+
326
+ class SubOwner < Owner
327
+ config_section :buffer do
328
+ config_set_default :size_of_something, 2048
329
+ end
330
+ end
331
+
332
+ class FlatChild
333
+ include Fluent::Configurable
334
+ attr_accessor :owner
335
+ config_param :key1, :string, default: "v1"
336
+ end
337
+
338
+ class BufferChild
339
+ include Fluent::Configurable
340
+ attr_accessor :owner
341
+ configured_in :buffer
342
+ config_param :size_of_something, :size, default: 128
343
+ end
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
351
+ end
352
+
353
+ module Fluent::Config
354
+ class TestConfigurable < ::Test::Unit::TestCase
355
+ sub_test_case 'class defined without config_section' do
356
+ sub_test_case '#initialize' do
357
+ test 'create instance methods and default values by config_param and config_set_default' do
358
+ obj1 = ConfigurableSpec::Base1.new
359
+ assert_equal("node", obj1.node)
360
+ assert_false(obj1.flag1)
361
+ assert_true(obj1.flag2)
362
+ assert_nil(obj1.name1)
363
+ assert_nil(obj1.name2)
364
+ assert_equal("base1", obj1.name3)
365
+ assert_equal("base1", obj1.name4)
366
+ assert_nil(obj1.opt1)
367
+ assert_equal(:foo, obj1.opt2)
368
+ end
369
+
370
+ test 'create instance methods and default values overwritten by sub class definition' do
371
+ obj2 = ConfigurableSpec::Base2.new
372
+ assert_equal("node", obj2.node)
373
+ assert_false(obj2.flag1)
374
+ assert_true(obj2.flag2)
375
+ assert_nil(obj2.name1)
376
+ assert_equal("base2", obj2.name2)
377
+ assert_equal("base1", obj2.name3)
378
+ assert_equal("base2", obj2.name4)
379
+ assert_nil(obj2.name5)
380
+ assert_equal("base2", obj2.name6)
381
+ assert_equal(:bar, obj2.opt1)
382
+ assert_equal(:foo, obj2.opt2)
383
+ end
384
+ end
385
+
386
+ sub_test_case '#configure' do
387
+ test 'returns configurable object itself' do
388
+ b2 = ConfigurableSpec::Base2.new
389
+ assert_instance_of(ConfigurableSpec::Base2, b2.configure(config_element("", "", {"name1" => "t1", "name5" => "t5", "opt3" => "a"})))
390
+ end
391
+
392
+ test 'raise errors without any specifications for param without defaults' do
393
+ b2 = ConfigurableSpec::Base2.new
394
+ assert_raise(Fluent::ConfigError) { b2.configure(config_element("", "", {})) }
395
+ assert_raise(Fluent::ConfigError) { b2.configure(config_element("", "", {"name1" => "t1"})) }
396
+ assert_raise(Fluent::ConfigError) { b2.configure(config_element("", "", {"name5" => "t5"})) }
397
+ assert_raise(Fluent::ConfigError) { b2.configure(config_element("", "", {"name1" => "t1", "name5" => "t5"})) }
398
+ assert_nothing_raised { b2.configure(config_element("", "", {"name1" => "t1", "name5" => "t5", "opt3" => "a"})) }
399
+
400
+ assert_equal(["node", false, true, "t1", "base2", "base1", "base2", "t5", "base2"], b2.get_all)
401
+ assert_equal(:a, b2.opt3)
402
+ end
403
+
404
+ test 'can configure bool values' do
405
+ b2a = ConfigurableSpec::Base2.new
406
+ assert_nothing_raised { b2a.configure(config_element("", "", {"flag1" => "true", "flag2" => "yes", "name1" => "t1", "name5" => "t5", "opt3" => "a"})) }
407
+ assert_true(b2a.flag1)
408
+ assert_true(b2a.flag2)
409
+
410
+ b2b = ConfigurableSpec::Base2.new
411
+ assert_nothing_raised { b2b.configure(config_element("", "", {"flag1" => false, "flag2" => "no", "name1" => "t1", "name5" => "t5", "opt3" => "a"})) }
412
+ assert_false(b2b.flag1)
413
+ assert_false(b2b.flag2)
414
+ end
415
+
416
+ test 'overwrites values of defaults' do
417
+ b2 = ConfigurableSpec::Base2.new
418
+ b2.configure(config_element("", "", {"name1" => "t1", "name2" => "t2", "name3" => "t3", "name4" => "t4", "name5" => "t5", "opt1" => "foo", "opt3" => "b"}))
419
+ assert_equal("t1", b2.name1)
420
+ assert_equal("t2", b2.name2)
421
+ assert_equal("t3", b2.name3)
422
+ assert_equal("t4", b2.name4)
423
+ assert_equal("t5", b2.name5)
424
+ assert_equal("base2", b2.name6)
425
+ assert_equal(:foo, b2.opt1)
426
+ assert_equal(:b, b2.opt3)
427
+
428
+ assert_equal(["node", false, true, "t1", "t2", "t3", "t4", "t5", "base2"], b2.get_all)
429
+ end
430
+
431
+ test 'enum type rejects values which does not exist in list' do
432
+ default = config_element("", "", {"name1" => "t1", "name2" => "t2", "name3" => "t3", "name4" => "t4", "name5" => "t5", "opt1" => "foo", "opt3" => "b"})
433
+
434
+ b2 = ConfigurableSpec::Base2.new
435
+ assert_nothing_raised { b2.configure(default) }
436
+ assert_raise(Fluent::ConfigError) { b2.configure(default.merge({"opt1" => "bazz"})) }
437
+ assert_raise(Fluent::ConfigError) { b2.configure(default.merge({"opt2" => "fooooooo"})) }
438
+ assert_raise(Fluent::ConfigError) { b2.configure(default.merge({"opt3" => "c"})) }
439
+ end
440
+
441
+ sub_test_case 'default values should be duplicated before touched in plugin code' do
442
+ test 'default object should be dupped for cases configured twice' do
443
+ x6a = ConfigurableSpec::Example6.new
444
+ assert_nothing_raised { x6a.configure(config_element("")) }
445
+ assert_equal({}, x6a.obj1)
446
+ assert_equal([], x6a.obj2)
447
+
448
+ x6b = ConfigurableSpec::Example6.new
449
+ assert_nothing_raised { x6b.configure(config_element("")) }
450
+ assert_equal({}, x6b.obj1)
451
+ assert_equal([], x6b.obj2)
452
+
453
+ assert { x6a.obj1.object_id != x6b.obj1.object_id }
454
+ assert { x6a.obj2.object_id != x6b.obj2.object_id }
455
+
456
+ x6c = ConfigurableSpec::Example6.new
457
+ assert_nothing_raised { x6c.configure(config_element("")) }
458
+ assert_equal({}, x6c.obj1)
459
+ assert_equal([], x6c.obj2)
460
+
461
+ x6c.obj1['k'] = 'v'
462
+ x6c.obj2 << 'v'
463
+
464
+ assert_equal({'k' => 'v'}, x6c.obj1)
465
+ assert_equal(['v'], x6c.obj2)
466
+
467
+ assert_equal({}, x6a.obj1)
468
+ assert_equal([], x6a.obj2)
469
+ end
470
+ end
471
+ end
472
+ end
473
+
474
+ sub_test_case 'class defined with config_section' do
475
+ sub_test_case '#initialize' do
476
+ test 'create instance methods and default values as nil for params from config_section specified as non-multi' do
477
+ b4 = ConfigurableSpec::Base4.new
478
+ assert_nil(b4.description1)
479
+ assert_nil(b4.description2)
480
+ end
481
+
482
+ test 'create instance methods and default values as [] for params from config_section specified as multi' do
483
+ b4 = ConfigurableSpec::Base4.new
484
+ assert_equal([], b4.description3)
485
+ end
486
+
487
+ test 'overwrite base class definition by config_section of sub class definition' do
488
+ b3 = ConfigurableSpec::Base3.new
489
+ assert_equal([], b3.node)
490
+ end
491
+
492
+ test 'create instance methods and default values by param_name' do
493
+ b4 = ConfigurableSpec::Base4.new
494
+ assert_equal([], b4.nodes)
495
+ assert_equal("node", b4.node)
496
+ end
497
+
498
+ test 'create non-required and multi without any specifications' do
499
+ b3 = ConfigurableSpec::Base3.new
500
+ assert_false(b3.class.merged_configure_proxy.sections[:node].required?)
501
+ assert_true(b3.class.merged_configure_proxy.sections[:node].multi?)
502
+ end
503
+ end
504
+
505
+ sub_test_case '#configure' do
506
+ BASE_ATTRS = {
507
+ "name1" => "1", "name2" => "2", "name3" => "3",
508
+ "name4" => "4", "name5" => "5", "name6" => "6",
509
+ }
510
+ test 'checks required subsections' do
511
+ b3 = ConfigurableSpec::Base3.new
512
+ # branch sections required
513
+ assert_raise(Fluent::ConfigError) { b3.configure(config_element('ROOT', '', BASE_ATTRS, [])) }
514
+
515
+ # branch argument required
516
+ msg = "'<branch ARG>' section requires argument, in section branch"
517
+ #expect{ b3.configure(e('ROOT', '', BASE_ATTRS, [e('branch', '')])) }.to raise_error(Fluent::ConfigError, msg)
518
+ assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(config_element('ROOT', '', BASE_ATTRS, [config_element('branch', '')])) }
519
+
520
+ # leaf is not required
521
+ assert_nothing_raised { b3.configure(config_element('ROOT', '', BASE_ATTRS, [config_element('branch', 'branch_name')])) }
522
+
523
+ # leaf weight required
524
+ msg = "'weight' parameter is required, in section branch > leaf"
525
+ branch1 = config_element('branch', 'branch_name', {size: 1}, [config_element('leaf', '10', {"weight" => 1})])
526
+ assert_nothing_raised { b3.configure(config_element('ROOT', '', BASE_ATTRS, [branch1])) }
527
+ branch2 = config_element('branch', 'branch_name', {size: 1}, [config_element('leaf', '20')])
528
+ assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(config_element('ROOT', '', BASE_ATTRS, [branch1, branch2])) }
529
+ branch3 = config_element('branch', 'branch_name', {size: 1}, [config_element('leaf', '10', {"weight" => 3}), config_element('leaf', '20')])
530
+ assert_raise(Fluent::ConfigError.new(msg)) { b3.configure(config_element('ROOT', '', BASE_ATTRS, [branch3])) }
531
+
532
+ ### worm not required
533
+
534
+ b4 = ConfigurableSpec::Base4.new
535
+
536
+ d1 = config_element('description1', '', {"text" => "d1"})
537
+ d2 = config_element('description2', '', {"text" => "d2"})
538
+ d3 = config_element('description3', '', {"text" => "d3"})
539
+ assert_nothing_raised { b4.configure(config_element('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup])) }
540
+
541
+ # description1 cannot be specified 2 or more
542
+ msg = "'<description1>' section cannot be written twice or more"
543
+ assert_raise(Fluent::ConfigError.new(msg)) { b4.configure(config_element('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d1.dup, d3.dup])) }
544
+
545
+ # description2 cannot be specified 2 or more
546
+ msg = "'<description2>' section cannot be written twice or more"
547
+ assert_raise(Fluent::ConfigError.new(msg)) { b4.configure(config_element('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup, d2.dup])) }
548
+
549
+ # description3 can be specified 2 or more
550
+ assert_nothing_raised { b4.configure(config_element('ROOT', '', BASE_ATTRS, [d1.dup, d2.dup, d3.dup, d3.dup])) }
551
+ end
552
+
553
+ test 'constructs confuguration object tree for Base3' do
554
+ conf = config_element(
555
+ 'ROOT',
556
+ '',
557
+ BASE_ATTRS,
558
+ [
559
+ config_element('node', '', {"type" => "1"}), config_element('node', '', {"name" => "node2","type" => "2"}),
560
+ config_element('branch', 'b1.*', {}, []),
561
+ config_element('branch',
562
+ 'b2.*',
563
+ {"size" => 5},
564
+ [
565
+ config_element('leaf', 'THIS IS IGNORED', {"weight" => 55}, []),
566
+ config_element('leaf', 'THIS IS IGNORED', {"weight" => 50}, [ config_element('worm', '', {}) ]),
567
+ config_element('leaf', 'THIS IS IGNORED', {"weight" => 50}, [ config_element('worm', '', {"type" => "w1"}), config_element('worm', '', {"type" => "w2"}) ]),
568
+ ]
569
+ ),
570
+ config_element('branch',
571
+ 'b3.*',
572
+ {"size" => "503"},
573
+ [
574
+ config_element('leaf', 'THIS IS IGNORED', {"weight" => 55}, []),
575
+ ]
576
+ )
577
+ ],
578
+ )
579
+ b3 = ConfigurableSpec::Base3.new.configure(conf)
580
+
581
+ assert_not_equal("node", b3.node) # overwritten
582
+
583
+ assert_equal("1", b3.name1)
584
+ assert_equal("2", b3.name2)
585
+ assert_equal("3", b3.name3)
586
+ assert_equal("4", b3.name4)
587
+ assert_equal("5", b3.name5)
588
+ assert_equal("6", b3.name6)
589
+
590
+ assert_instance_of(Array, b3.node)
591
+ assert_equal(2, b3.node.size)
592
+
593
+ assert_equal("node", b3.node[0].name)
594
+ assert_equal("1", b3.node[0].type)
595
+ assert_equal(b3.node[0].type, b3.node[0][:type])
596
+ assert_equal("node2", b3.node[1].name)
597
+ assert_equal("2", b3.node[1].type)
598
+ assert_equal(b3.node[1].type, b3.node[1][:type])
599
+
600
+ assert_instance_of(Array, b3.branch)
601
+ assert_equal(3, b3.branch.size)
602
+
603
+ assert_equal('b1.*', b3.branch[0].name)
604
+ assert_equal(10, b3.branch[0].size)
605
+ assert_equal([], b3.branch[0].leaf)
606
+
607
+ assert_equal('b2.*', b3.branch[1].name)
608
+ assert_equal(5, b3.branch[1].size)
609
+ assert_equal(3, b3.branch[1].leaf.size)
610
+ assert_equal(b3.branch[1].leaf, b3.branch[1][:leaf])
611
+
612
+ assert_equal(55, b3.branch[1].leaf[0].weight)
613
+ assert_equal(0, b3.branch[1].leaf[0].worms.size)
614
+
615
+ assert_equal(50, b3.branch[1].leaf[1].weight)
616
+ assert_equal(1, b3.branch[1].leaf[1].worms.size)
617
+ assert_equal("ladybird", b3.branch[1].leaf[1].worms[0].type)
618
+
619
+ assert_equal(50, b3.branch[1].leaf[2].weight)
620
+ assert_equal(2, b3.branch[1].leaf[2].worms.size)
621
+ assert_equal("w1", b3.branch[1].leaf[2].worms[0].type)
622
+ assert_equal("w2", b3.branch[1].leaf[2].worms[1].type)
623
+
624
+ assert_equal('b3.*', b3.branch[2].name)
625
+ assert_equal(503, b3.branch[2].size)
626
+ assert_equal(1, b3.branch[2].leaf.size)
627
+ assert_equal(55, b3.branch[2].leaf[0].weight)
628
+ end
629
+
630
+ test 'constructs confuguration object tree for Base4' do
631
+ conf = config_element(
632
+ 'ROOT',
633
+ '',
634
+ BASE_ATTRS,
635
+ [
636
+ config_element('node', '1', {"type" => "1"}), config_element('node', '2', {"name" => "node2"}),
637
+ config_element('description3', '', {"text" => "dddd3-1"}),
638
+ config_element('description2', 'd-2', {"text" => "dddd2"}),
639
+ config_element('description1', '', {"text" => "dddd1"}),
640
+ config_element('description3', 'd-3', {"text" => "dddd3-2"}),
641
+ config_element('description3', 'd-3a', {"text" => "dddd3-3"}),
642
+ config_element('node', '4', {"type" => "four"}),
643
+ ],
644
+ )
645
+ b4 = ConfigurableSpec::Base4.new.configure(conf)
646
+
647
+ assert_equal("node", b4.node)
648
+
649
+ assert_equal("1", b4.name1)
650
+ assert_equal("2", b4.name2)
651
+ assert_equal("3", b4.name3)
652
+ assert_equal("4", b4.name4)
653
+ assert_equal("5", b4.name5)
654
+ assert_equal("6", b4.name6)
655
+
656
+ assert_instance_of(Array, b4.nodes)
657
+ assert_equal(3, b4.nodes.size)
658
+ assert_equal(1, b4.nodes[0].num)
659
+ assert_equal("node", b4.nodes[0].name)
660
+ assert_equal("1", b4.nodes[0].type)
661
+ assert_equal(2, b4.nodes[1].num)
662
+ assert_equal("node2", b4.nodes[1].name)
663
+ assert_equal("b4", b4.nodes[1].type)
664
+ assert_equal(4, b4.nodes[2].num)
665
+ assert_equal("node", b4.nodes[2].name)
666
+ assert_equal("four", b4.nodes[2].type)
667
+
668
+ # config_element('description3', '', {"text" => "dddd3-1"}),
669
+ # config_element('description3', 'd-3', {"text" => "dddd3-2"}),
670
+ # config_element('description3', 'd-3a', {"text" => "dddd3-3"}),
671
+
672
+ # NoMethodError: undefined method `class' for <Fluent::Config::Section {...}>:Fluent::Config::Section occurred. Should we add class method to Section?
673
+ #assert_equal('Fluent::Config::Section', b4.description1.class.name)
674
+ assert_equal("desc1", b4.description1.note)
675
+ assert_equal("dddd1", b4.description1.text)
676
+
677
+ # same with assert_equal('Fluent::Config::Section', b4.description1)
678
+ #assert_equal('Fluent::Config::Section', b4.description2)
679
+ assert_equal("d-2", b4.description2.note)
680
+ assert_equal("dddd2", b4.description2.text)
681
+
682
+ assert_instance_of(Array, b4.description3)
683
+ assert_equal(3, b4.description3.size)
684
+ assert_equal("desc3", b4.description3[0].note)
685
+ assert_equal("dddd3-1", b4.description3[0].text)
686
+ assert_equal('desc3: d-3', b4.description3[1].note)
687
+ assert_equal('dddd3-2', b4.description3[1].text)
688
+ assert_equal('desc3: d-3a', b4.description3[2].note)
689
+ assert_equal('dddd3-3', b4.description3[2].text)
690
+ end
691
+
692
+ test 'checks missing of specifications' do
693
+ conf0 = config_element('ROOT', '', {}, [])
694
+ ex01 = ConfigurableSpec::Example0.new
695
+ assert_raise(Fluent::ConfigError) { ex01.configure(conf0) }
696
+
697
+ complete = config_element('ROOT', '', {
698
+ "stringvalue" => "s1", "boolvalue" => "yes", "integervalue" => "10",
699
+ "sizevalue" => "10m", "timevalue" => "100s", "floatvalue" => "1.001",
700
+ "hashvalue" => '{"foo":1, "bar":2}',
701
+ "arrayvalue" => '[1,"ichi"]',
702
+ })
703
+
704
+ checker = lambda { |conf| ConfigurableSpec::Example0.new.configure(conf) }
705
+
706
+ assert_nothing_raised { checker.call(complete) }
707
+ assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("stringvalue"); checker.call(c) }
708
+ assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("boolvalue"); checker.call(c) }
709
+ assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("integervalue"); checker.call(c) }
710
+ assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("sizevalue"); checker.call(c) }
711
+ assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("timevalue"); checker.call(c) }
712
+ assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("floatvalue"); checker.call(c) }
713
+ assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("hashvalue"); checker.call(c) }
714
+ assert_raise(Fluent::ConfigError) { c = complete.dup; c.delete("arrayvalue"); checker.call(c) }
715
+ end
716
+
717
+ test 'generates section with default values for init:true sections' do
718
+ conf = config_element('ROOT', '', {}, [])
719
+ init0 = ConfigurableSpec::Init0.new
720
+ assert_nothing_raised { init0.configure(conf) }
721
+ assert init0.sec1
722
+ assert_equal "sec1", init0.sec1.name
723
+ assert_equal [], init0.sec2
724
+ end
725
+
726
+ test 'accepts configuration values as string representation' do
727
+ conf = config_element('ROOT', '', {
728
+ "stringvalue" => "s1", "boolvalue" => "yes", "integervalue" => "10",
729
+ "sizevalue" => "10m", "timevalue" => "10m", "floatvalue" => "1.001",
730
+ "hashvalue" => '{"foo":1, "bar":2}',
731
+ "arrayvalue" => '[1,"ichi"]',
732
+ })
733
+ ex = ConfigurableSpec::Example0.new.configure(conf)
734
+ assert_equal("s1", ex.stringvalue)
735
+ assert_true(ex.boolvalue)
736
+ assert_equal(10, ex.integervalue)
737
+ assert_equal(10 * 1024 * 1024, ex.sizevalue)
738
+ assert_equal(10 * 60, ex.timevalue)
739
+ assert_equal(1.001, ex.floatvalue)
740
+ assert_equal({"foo" => 1, "bar" => 2}, ex.hashvalue)
741
+ assert_equal([1, "ichi"], ex.arrayvalue)
742
+ end
743
+
744
+ test 'accepts configuration values as ruby value representation (especially for DSL)' do
745
+ conf = config_element('ROOT', '', {
746
+ "stringvalue" => "s1", "boolvalue" => true, "integervalue" => 10,
747
+ "sizevalue" => 10 * 1024 * 1024, "timevalue" => 10 * 60, "floatvalue" => 1.001,
748
+ "hashvalue" => {"foo" => 1, "bar" => 2},
749
+ "arrayvalue" => [1,"ichi"],
750
+ })
751
+ ex = ConfigurableSpec::Example0.new.configure(conf)
752
+ assert_equal("s1", ex.stringvalue)
753
+ assert_true(ex.boolvalue)
754
+ assert_equal(10, ex.integervalue)
755
+ assert_equal(10 * 1024 * 1024, ex.sizevalue)
756
+ assert_equal(10 * 60, ex.timevalue)
757
+ assert_equal(1.001, ex.floatvalue)
758
+ assert_equal({"foo" => 1, "bar" => 2}, ex.hashvalue)
759
+ assert_equal([1, "ichi"], ex.arrayvalue)
760
+ end
761
+
762
+ test 'gets both of true(yes) and false(no) for bool value parameter' do
763
+ conf = config_element('ROOT', '', {
764
+ "stringvalue" => "s1", "integervalue" => 10,
765
+ "sizevalue" => 10 * 1024 * 1024, "timevalue" => 10 * 60, "floatvalue" => 1.001,
766
+ "hashvalue" => {"foo" => 1, "bar" => 2},
767
+ "arrayvalue" => [1,"ichi"],
768
+ })
769
+ ex0 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => "true"}))
770
+ assert_true(ex0.boolvalue)
771
+
772
+ ex1 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => "yes"}))
773
+ assert_true(ex1.boolvalue)
774
+
775
+ ex2 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => true}))
776
+ assert_true(ex2.boolvalue)
777
+
778
+ ex3 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => "false"}))
779
+ assert_false(ex3.boolvalue)
780
+
781
+ ex4 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => "no"}))
782
+ assert_false(ex4.boolvalue)
783
+
784
+ ex5 = ConfigurableSpec::Example0.new.configure(conf.merge({"boolvalue" => false}))
785
+ assert_false(ex5.boolvalue)
786
+ end
787
+ end
788
+
789
+ sub_test_case '.config_section' do
790
+ CONF1 = config_element('ROOT', '', {
791
+ 'name' => 'tagomoris',
792
+ 'bool' => true,
793
+ })
794
+
795
+ CONF2 = config_element('ROOT', '', {
796
+ 'name' => 'tagomoris',
797
+ 'bool' => true,
798
+ },
799
+ [config_element('detail', '', { 'phone_no' => "+81-00-0000-0000" }, [])])
800
+
801
+ CONF3 = config_element('ROOT', '', {
802
+ 'name' => 'tagomoris',
803
+ 'bool' => true,
804
+ },
805
+ [config_element('detail', '', { 'address' => "Chiyoda Tokyo Japan" }, [])])
806
+
807
+ CONF4 = config_element('ROOT', '', {
808
+ 'name' => 'tagomoris',
809
+ 'bool' => true,
810
+ },
811
+ [
812
+ config_element('detail', '', {
813
+ 'address' => "Chiyoda Tokyo Japan",
814
+ 'phone_no' => '+81-00-0000-0000'
815
+ },
816
+ [])
817
+ ])
818
+
819
+ data(conf1: CONF1,
820
+ conf2: CONF2,
821
+ conf3: CONF3,
822
+ conf4: CONF4,)
823
+ test 'base class' do |data|
824
+ assert_nothing_raised { ConfigurableSpec::Overwrite::Base.new.configure(data) }
825
+ end
826
+
827
+ test 'subclass cannot overwrite required' do
828
+ assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: required")) do
829
+ ConfigurableSpec::Overwrite::Required.new.configure(CONF1)
830
+ end
831
+ end
832
+
833
+ test 'subclass cannot overwrite multi' do
834
+ assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: multi")) do
835
+ ConfigurableSpec::Overwrite::Multi.new.configure(CONF1)
836
+ end
837
+ end
838
+
839
+ test 'subclass cannot overwrite alias' do
840
+ assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: alias")) do
841
+ ConfigurableSpec::Overwrite::Alias.new.configure(CONF1)
842
+ end
843
+ end
844
+
845
+ test 'subclass uses superclass default options' do
846
+ base = ConfigurableSpec::Overwrite::Base.new.configure(CONF2)
847
+ sub = ConfigurableSpec::Overwrite::DefaultOptions.new.configure(CONF2)
848
+ detail_base = base.class.merged_configure_proxy.sections[:detail]
849
+ detail_sub = sub.class.merged_configure_proxy.sections[:detail]
850
+ detail_base_attributes = {
851
+ requried: detail_base.required,
852
+ multi: detail_base.multi,
853
+ alias: detail_base.alias,
854
+ }
855
+ detail_sub_attributes = {
856
+ requried: detail_sub.required,
857
+ multi: detail_sub.multi,
858
+ alias: detail_sub.alias,
859
+ }
860
+ assert_equal(detail_base_attributes, detail_sub_attributes)
861
+ end
862
+
863
+ test 'subclass can overwrite detail.address' do
864
+ base = ConfigurableSpec::Overwrite::Base.new.configure(CONF2)
865
+ target = ConfigurableSpec::Overwrite::DetailAddressDefault.new.configure(CONF2)
866
+ expected_addresses = ["x", "y"]
867
+ actual_addresses = [base.detail.address, target.detail.address]
868
+ assert_equal(expected_addresses, actual_addresses)
869
+ end
870
+
871
+ test 'subclass can add param' do
872
+ assert_raise(Fluent::ConfigError.new("'phone_no' parameter is required, in section detail")) do
873
+ ConfigurableSpec::Overwrite::AddParam.new.configure(CONF3)
874
+ end
875
+ target = ConfigurableSpec::Overwrite::AddParam.new.configure(CONF4)
876
+ expected = {
877
+ address: "Chiyoda Tokyo Japan",
878
+ phone_no: "+81-00-0000-0000"
879
+ }
880
+ actual = {
881
+ address: target.detail.address,
882
+ phone_no: target.detail.phone_no
883
+ }
884
+ assert_equal(expected, actual)
885
+ end
886
+
887
+ test 'subclass can add param with overwriting address' do
888
+ assert_raise(Fluent::ConfigError.new("'phone_no' parameter is required, in section detail")) do
889
+ ConfigurableSpec::Overwrite::AddParamOverwriteAddress.new.configure(CONF3)
890
+ end
891
+ target = ConfigurableSpec::Overwrite::AddParamOverwriteAddress.new.configure(CONF4)
892
+ expected = {
893
+ address: "Chiyoda Tokyo Japan",
894
+ phone_no: "+81-00-0000-0000"
895
+ }
896
+ actual = {
897
+ address: target.detail.address,
898
+ phone_no: target.detail.phone_no
899
+ }
900
+ assert_equal(expected, actual)
901
+ end
902
+
903
+ sub_test_case 'final' do
904
+ test 'base class has designed params and default values' do
905
+ b = ConfigurableSpec::Final::Base.new
906
+ appendix_conf = config_element('appendix', '', {"code" => "b", "name" => "base"})
907
+ b.configure(config_element('ROOT', '', {}, [appendix_conf]))
908
+
909
+ assert_equal "b", b.appendix.code
910
+ assert_equal "base", b.appendix.name
911
+ assert_equal "", b.appendix.address
912
+ end
913
+
914
+ test 'subclass can change type, add default value, change default value of parameters, and add parameters to non-finalized section' do
915
+ f = ConfigurableSpec::Final::Finalized.new
916
+ appendix_conf = config_element('appendix', '', {"code" => 1})
917
+ f.configure(config_element('ROOT', '', {}, [appendix_conf]))
918
+
919
+ assert_equal 1, f.appendix.code
920
+ assert_equal 'y', f.appendix.name
921
+ assert_equal "-", f.appendix.address
922
+ assert_equal 10, f.appendix.age
923
+ end
924
+
925
+ test 'subclass can add default value, change default value of parameters, and add parameters to finalized section' do
926
+ i = ConfigurableSpec::Final::InheritsFinalized.new
927
+ appendix_conf = config_element('appendix', '', {"phone_no" => "00-0000-0000"})
928
+ i.configure(config_element('ROOT', '', {}, [appendix_conf]))
929
+
930
+ assert_equal 2, i.appendix.code
931
+ assert_equal 0, i.appendix.age
932
+ assert_equal "00-0000-0000", i.appendix.phone_no
933
+ end
934
+
935
+ test 'finalized base class works as designed' do
936
+ b = ConfigurableSpec::Final::FinalizedBase.new
937
+ appendix_conf = config_element('options', '', {"name" => "moris"})
938
+
939
+ assert_nothing_raised do
940
+ b.configure(config_element('ROOT', '', {}, [appendix_conf]))
941
+ end
942
+ assert b.apd
943
+ assert_equal "moris", b.apd.name
944
+ end
945
+
946
+ test 'subclass can change init' do
947
+ n = ConfigurableSpec::Final::OverwriteInit.new
948
+
949
+ assert_nothing_raised do
950
+ n.configure(config_element('ROOT', ''))
951
+ end
952
+ assert n.apd
953
+ assert_equal "moris", n.apd.name
954
+ assert_equal 0, n.apd.code
955
+ end
956
+
957
+ test 'subclass cannot change parameter types in finalized sections' do
958
+ s = ConfigurableSpec::Final::Subclass.new
959
+ appendix_conf = config_element('options', '', {"name" => "1"})
960
+
961
+ assert_nothing_raised do
962
+ s.configure(config_element('ROOT', '', {}, [appendix_conf]))
963
+ end
964
+ assert_equal "1", s.apd.name
965
+ end
966
+
967
+ test 'subclass cannot change param_name of finalized section' do
968
+ assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: param_name")) do
969
+ ConfigurableSpec::Final::OverwriteParamName.new
970
+ end
971
+ end
972
+
973
+ test 'subclass cannot change final of finalized section' do
974
+ assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite finalized base class's config_section")) do
975
+ ConfigurableSpec::Final::OverwriteFinal.new
976
+ end
977
+ end
978
+
979
+ test 'subclass cannot change required of finalized section' do
980
+ assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: required")) do
981
+ ConfigurableSpec::Final::OverwriteRequired.new
982
+ end
983
+ end
984
+
985
+ test 'subclass cannot change multi of finalized section' do
986
+ assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: multi")) do
987
+ ConfigurableSpec::Final::OverwriteMulti.new
988
+ end
989
+ end
990
+
991
+ test 'subclass cannot change alias of finalized section' do
992
+ assert_raise(Fluent::ConfigError.new("BUG: subclass cannot overwrite base class's config_section: alias")) do
993
+ ConfigurableSpec::Final::OverwriteAlias.new
994
+ end
995
+ end
996
+ end
997
+ end
998
+ end
999
+
1000
+ sub_test_case 'class defined with config_param/config_section having :alias' do
1001
+ sub_test_case '#initialize' do
1002
+ test 'does not create methods for alias' do
1003
+ ex1 = ConfigurableSpec::Example1.new
1004
+ assert_nothing_raised { ex1.name }
1005
+ assert_raise(NoMethodError) { ex1.fullname }
1006
+ assert_nothing_raised { ex1.bool }
1007
+ assert_raise(NoMethodError) { ex1.flag }
1008
+ assert_nothing_raised { ex1.detail }
1009
+ assert_raise(NoMethodError) { ex1.information}
1010
+ end
1011
+ end
1012
+
1013
+ sub_test_case '#configure' do
1014
+ test 'provides accessible data for alias attribute keys' do
1015
+ ex1 = ConfigurableSpec::Example1.new
1016
+ conf = config_element('ROOT', '', {
1017
+ "fullname" => "foo bar",
1018
+ "bool" => false
1019
+ },
1020
+ [config_element('information', '', {"address" => "Mountain View 0"})])
1021
+ ex1.configure(conf)
1022
+ assert_equal("foo bar", ex1.name)
1023
+ assert_not_nil(ex1.bool)
1024
+ assert_false(ex1.bool)
1025
+ assert_not_nil(ex1.detail)
1026
+ assert_equal("Mountain View 0", ex1.detail.address)
1027
+ end
1028
+ end
1029
+ end
1030
+
1031
+ sub_test_case 'defaults can be overwritten by owner' do
1032
+ test 'for feature plugin which has flat parameters with parent' do
1033
+ owner = ConfigurableSpec::OverwriteDefaults::Owner.new
1034
+ child = ConfigurableSpec::OverwriteDefaults::FlatChild.new
1035
+ child.owner = owner
1036
+ child.configure(config_element('ROOT', '', {}, []))
1037
+ assert_equal "V1", child.key1
1038
+ end
1039
+
1040
+ test 'for feature plugin which has parameters in subsection of parent' do
1041
+ owner = ConfigurableSpec::OverwriteDefaults::Owner.new
1042
+ child = ConfigurableSpec::OverwriteDefaults::BufferChild.new
1043
+ child.owner = owner
1044
+ child.configure(config_element('ROOT', '', {}, []))
1045
+ assert_equal 1024, child.size_of_something
1046
+ end
1047
+
1048
+ test 'even in subclass of owner' do
1049
+ owner = ConfigurableSpec::OverwriteDefaults::SubOwner.new
1050
+ child = ConfigurableSpec::OverwriteDefaults::BufferChild.new
1051
+ child.owner = owner
1052
+ child.configure(config_element('ROOT', '', {}, []))
1053
+ assert_equal 2048, child.size_of_something
1054
+ end
1055
+ end
1056
+
1057
+ sub_test_case ':secret option' do
1058
+ setup do
1059
+ @conf = config_element('ROOT', '',
1060
+ {
1061
+ 'normal_param' => 'normal',
1062
+ 'secret_param' => 'secret'
1063
+ },
1064
+ [config_element('section', '', {'normal_param2' => 'normal', 'secret_param2' => 'secret'} )])
1065
+ @example = ConfigurableSpec::Example5.new
1066
+ @example.configure(@conf)
1067
+ end
1068
+
1069
+ test 'to_s hides secret config_param' do
1070
+ @conf.to_s.each_line { |line|
1071
+ key, value = line.strip.split(' ', 2)
1072
+ assert_secret_param(key, value)
1073
+ }
1074
+ end
1075
+
1076
+ test 'config returns masked configuration' do
1077
+ conf = @example.config
1078
+ conf.each_pair { |key, value|
1079
+ assert_secret_param(key, value)
1080
+ }
1081
+ conf.elements.each { |element|
1082
+ element.each_pair { |key, value|
1083
+ assert_secret_param(key, value)
1084
+ }
1085
+ }
1086
+ end
1087
+
1088
+ test 'get plugin name when found unknown section' do
1089
+ @conf = config_element('ROOT', '',
1090
+ {
1091
+ 'normal_param' => 'normal',
1092
+ 'secret_param' => 'secret'
1093
+ },
1094
+ [config_element('unknown', '', {'normal_param2' => 'normal', 'secret_param2' => 'secret'} )])
1095
+ @example = ConfigurableSpec::Example5.new
1096
+ @example.configure(@conf)
1097
+ @conf.elements.each { |e|
1098
+ assert_equal(['ROOT', nil], e.unused_in)
1099
+ }
1100
+ end
1101
+
1102
+ def assert_secret_param(key, value)
1103
+ case key
1104
+ when 'normal_param', 'normal_param2'
1105
+ assert_equal 'normal', value
1106
+ when 'secret_param', 'secret_param2'
1107
+ assert_equal 'xxxxxx', value
1108
+ end
1109
+ end
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
1193
+ end
1194
+ end