dtomasgu-fluentd 1.14.7.pre.dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (564) hide show
  1. checksums.yaml +7 -0
  2. data/.deepsource.toml +13 -0
  3. data/.drone.yml +35 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.yaml +70 -0
  5. data/.github/ISSUE_TEMPLATE/config.yml +5 -0
  6. data/.github/ISSUE_TEMPLATE/feature_request.yaml +38 -0
  7. data/.github/ISSUE_TEMPLATE.md +17 -0
  8. data/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  9. data/.github/workflows/issue-auto-closer.yml +12 -0
  10. data/.github/workflows/linux-test.yaml +36 -0
  11. data/.github/workflows/macos-test.yaml +34 -0
  12. data/.github/workflows/stale-actions.yml +22 -0
  13. data/.github/workflows/windows-test.yaml +49 -0
  14. data/.gitignore +30 -0
  15. data/.gitlab-ci.yml +103 -0
  16. data/ADOPTERS.md +5 -0
  17. data/AUTHORS +2 -0
  18. data/CHANGELOG.md +2453 -0
  19. data/CONTRIBUTING.md +45 -0
  20. data/GOVERNANCE.md +55 -0
  21. data/Gemfile +9 -0
  22. data/GithubWorkflow.md +78 -0
  23. data/LICENSE +202 -0
  24. data/MAINTAINERS.md +11 -0
  25. data/README.md +76 -0
  26. data/Rakefile +79 -0
  27. data/SECURITY.md +18 -0
  28. data/bin/fluent-binlog-reader +7 -0
  29. data/bin/fluent-ca-generate +6 -0
  30. data/bin/fluent-cap-ctl +7 -0
  31. data/bin/fluent-cat +5 -0
  32. data/bin/fluent-ctl +7 -0
  33. data/bin/fluent-debug +5 -0
  34. data/bin/fluent-gem +9 -0
  35. data/bin/fluent-plugin-config-format +5 -0
  36. data/bin/fluent-plugin-generate +5 -0
  37. data/bin/fluentd +15 -0
  38. data/code-of-conduct.md +3 -0
  39. data/docs/SECURITY_AUDIT.pdf +0 -0
  40. data/example/copy_roundrobin.conf +39 -0
  41. data/example/counter.conf +18 -0
  42. data/example/filter_stdout.conf +22 -0
  43. data/example/in_forward.conf +14 -0
  44. data/example/in_forward_client.conf +37 -0
  45. data/example/in_forward_shared_key.conf +15 -0
  46. data/example/in_forward_tls.conf +14 -0
  47. data/example/in_forward_users.conf +24 -0
  48. data/example/in_forward_workers.conf +21 -0
  49. data/example/in_http.conf +16 -0
  50. data/example/in_out_forward.conf +17 -0
  51. data/example/in_sample_blocks.conf +17 -0
  52. data/example/in_sample_with_compression.conf +23 -0
  53. data/example/in_syslog.conf +15 -0
  54. data/example/in_tail.conf +14 -0
  55. data/example/in_tcp.conf +13 -0
  56. data/example/in_udp.conf +13 -0
  57. data/example/logevents.conf +25 -0
  58. data/example/multi_filters.conf +61 -0
  59. data/example/out_copy.conf +20 -0
  60. data/example/out_exec_filter.conf +42 -0
  61. data/example/out_file.conf +13 -0
  62. data/example/out_forward.conf +35 -0
  63. data/example/out_forward_buf_file.conf +23 -0
  64. data/example/out_forward_client.conf +109 -0
  65. data/example/out_forward_heartbeat_none.conf +16 -0
  66. data/example/out_forward_sd.conf +17 -0
  67. data/example/out_forward_shared_key.conf +36 -0
  68. data/example/out_forward_tls.conf +18 -0
  69. data/example/out_forward_users.conf +65 -0
  70. data/example/out_null.conf +36 -0
  71. data/example/sd.yaml +8 -0
  72. data/example/secondary_file.conf +42 -0
  73. data/example/suppress_config_dump.conf +7 -0
  74. data/example/v0_12_filter.conf +78 -0
  75. data/example/v1_literal_example.conf +36 -0
  76. data/example/worker_section.conf +36 -0
  77. data/fluent.conf +139 -0
  78. data/fluentd.gemspec +57 -0
  79. data/lib/fluent/agent.rb +168 -0
  80. data/lib/fluent/capability.rb +87 -0
  81. data/lib/fluent/clock.rb +66 -0
  82. data/lib/fluent/command/binlog_reader.rb +244 -0
  83. data/lib/fluent/command/bundler_injection.rb +45 -0
  84. data/lib/fluent/command/ca_generate.rb +184 -0
  85. data/lib/fluent/command/cap_ctl.rb +174 -0
  86. data/lib/fluent/command/cat.rb +365 -0
  87. data/lib/fluent/command/ctl.rb +180 -0
  88. data/lib/fluent/command/debug.rb +103 -0
  89. data/lib/fluent/command/fluentd.rb +388 -0
  90. data/lib/fluent/command/plugin_config_formatter.rb +308 -0
  91. data/lib/fluent/command/plugin_generator.rb +365 -0
  92. data/lib/fluent/compat/call_super_mixin.rb +76 -0
  93. data/lib/fluent/compat/detach_process_mixin.rb +33 -0
  94. data/lib/fluent/compat/exec_util.rb +129 -0
  95. data/lib/fluent/compat/file_util.rb +54 -0
  96. data/lib/fluent/compat/filter.rb +68 -0
  97. data/lib/fluent/compat/formatter.rb +111 -0
  98. data/lib/fluent/compat/formatter_utils.rb +85 -0
  99. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  100. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  101. data/lib/fluent/compat/input.rb +49 -0
  102. data/lib/fluent/compat/output.rb +721 -0
  103. data/lib/fluent/compat/output_chain.rb +60 -0
  104. data/lib/fluent/compat/parser.rb +310 -0
  105. data/lib/fluent/compat/parser_utils.rb +40 -0
  106. data/lib/fluent/compat/propagate_default.rb +62 -0
  107. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  108. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  109. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  110. data/lib/fluent/compat/socket_util.rb +165 -0
  111. data/lib/fluent/compat/string_util.rb +34 -0
  112. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  113. data/lib/fluent/compat/type_converter.rb +90 -0
  114. data/lib/fluent/config/basic_parser.rb +123 -0
  115. data/lib/fluent/config/configure_proxy.rb +424 -0
  116. data/lib/fluent/config/dsl.rb +152 -0
  117. data/lib/fluent/config/element.rb +265 -0
  118. data/lib/fluent/config/error.rb +44 -0
  119. data/lib/fluent/config/literal_parser.rb +286 -0
  120. data/lib/fluent/config/parser.rb +107 -0
  121. data/lib/fluent/config/section.rb +272 -0
  122. data/lib/fluent/config/types.rb +249 -0
  123. data/lib/fluent/config/v1_parser.rb +192 -0
  124. data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
  125. data/lib/fluent/config/yaml_parser/loader.rb +91 -0
  126. data/lib/fluent/config/yaml_parser/parser.rb +166 -0
  127. data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
  128. data/lib/fluent/config/yaml_parser.rb +56 -0
  129. data/lib/fluent/config.rb +89 -0
  130. data/lib/fluent/configurable.rb +201 -0
  131. data/lib/fluent/counter/base_socket.rb +44 -0
  132. data/lib/fluent/counter/client.rb +297 -0
  133. data/lib/fluent/counter/error.rb +86 -0
  134. data/lib/fluent/counter/mutex_hash.rb +163 -0
  135. data/lib/fluent/counter/server.rb +273 -0
  136. data/lib/fluent/counter/store.rb +205 -0
  137. data/lib/fluent/counter/validator.rb +145 -0
  138. data/lib/fluent/counter.rb +23 -0
  139. data/lib/fluent/daemon.rb +15 -0
  140. data/lib/fluent/daemonizer.rb +88 -0
  141. data/lib/fluent/engine.rb +253 -0
  142. data/lib/fluent/env.rb +40 -0
  143. data/lib/fluent/error.rb +34 -0
  144. data/lib/fluent/event.rb +326 -0
  145. data/lib/fluent/event_router.rb +315 -0
  146. data/lib/fluent/ext_monitor_require.rb +28 -0
  147. data/lib/fluent/filter.rb +21 -0
  148. data/lib/fluent/fluent_log_event_router.rb +141 -0
  149. data/lib/fluent/formatter.rb +23 -0
  150. data/lib/fluent/input.rb +21 -0
  151. data/lib/fluent/label.rb +46 -0
  152. data/lib/fluent/load.rb +34 -0
  153. data/lib/fluent/log.rb +713 -0
  154. data/lib/fluent/match.rb +187 -0
  155. data/lib/fluent/mixin.rb +31 -0
  156. data/lib/fluent/msgpack_factory.rb +106 -0
  157. data/lib/fluent/oj_options.rb +62 -0
  158. data/lib/fluent/output.rb +29 -0
  159. data/lib/fluent/output_chain.rb +23 -0
  160. data/lib/fluent/parser.rb +23 -0
  161. data/lib/fluent/plugin/bare_output.rb +104 -0
  162. data/lib/fluent/plugin/base.rb +197 -0
  163. data/lib/fluent/plugin/buf_file.rb +213 -0
  164. data/lib/fluent/plugin/buf_file_single.rb +225 -0
  165. data/lib/fluent/plugin/buf_memory.rb +34 -0
  166. data/lib/fluent/plugin/buffer/chunk.rb +240 -0
  167. data/lib/fluent/plugin/buffer/file_chunk.rb +413 -0
  168. data/lib/fluent/plugin/buffer/file_single_chunk.rb +311 -0
  169. data/lib/fluent/plugin/buffer/memory_chunk.rb +91 -0
  170. data/lib/fluent/plugin/buffer.rb +918 -0
  171. data/lib/fluent/plugin/compressable.rb +96 -0
  172. data/lib/fluent/plugin/exec_util.rb +22 -0
  173. data/lib/fluent/plugin/file_util.rb +22 -0
  174. data/lib/fluent/plugin/file_wrapper.rb +132 -0
  175. data/lib/fluent/plugin/filter.rb +127 -0
  176. data/lib/fluent/plugin/filter_grep.rb +189 -0
  177. data/lib/fluent/plugin/filter_parser.rb +130 -0
  178. data/lib/fluent/plugin/filter_record_transformer.rb +324 -0
  179. data/lib/fluent/plugin/filter_stdout.rb +53 -0
  180. data/lib/fluent/plugin/formatter.rb +75 -0
  181. data/lib/fluent/plugin/formatter_csv.rb +78 -0
  182. data/lib/fluent/plugin/formatter_hash.rb +35 -0
  183. data/lib/fluent/plugin/formatter_json.rb +59 -0
  184. data/lib/fluent/plugin/formatter_ltsv.rb +44 -0
  185. data/lib/fluent/plugin/formatter_msgpack.rb +33 -0
  186. data/lib/fluent/plugin/formatter_out_file.rb +53 -0
  187. data/lib/fluent/plugin/formatter_single_value.rb +36 -0
  188. data/lib/fluent/plugin/formatter_stdout.rb +76 -0
  189. data/lib/fluent/plugin/formatter_tsv.rb +40 -0
  190. data/lib/fluent/plugin/in_debug_agent.rb +71 -0
  191. data/lib/fluent/plugin/in_dummy.rb +18 -0
  192. data/lib/fluent/plugin/in_exec.rb +110 -0
  193. data/lib/fluent/plugin/in_forward.rb +473 -0
  194. data/lib/fluent/plugin/in_gc_stat.rb +72 -0
  195. data/lib/fluent/plugin/in_http.rb +677 -0
  196. data/lib/fluent/plugin/in_monitor_agent.rb +412 -0
  197. data/lib/fluent/plugin/in_object_space.rb +93 -0
  198. data/lib/fluent/plugin/in_sample.rb +141 -0
  199. data/lib/fluent/plugin/in_syslog.rb +276 -0
  200. data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
  201. data/lib/fluent/plugin/in_tail/position_file.rb +255 -0
  202. data/lib/fluent/plugin/in_tail.rb +1247 -0
  203. data/lib/fluent/plugin/in_tcp.rb +181 -0
  204. data/lib/fluent/plugin/in_udp.rb +92 -0
  205. data/lib/fluent/plugin/in_unix.rb +195 -0
  206. data/lib/fluent/plugin/input.rb +75 -0
  207. data/lib/fluent/plugin/metrics.rb +119 -0
  208. data/lib/fluent/plugin/metrics_local.rb +96 -0
  209. data/lib/fluent/plugin/multi_output.rb +195 -0
  210. data/lib/fluent/plugin/out_copy.rb +120 -0
  211. data/lib/fluent/plugin/out_exec.rb +105 -0
  212. data/lib/fluent/plugin/out_exec_filter.rb +319 -0
  213. data/lib/fluent/plugin/out_file.rb +334 -0
  214. data/lib/fluent/plugin/out_forward/ack_handler.rb +161 -0
  215. data/lib/fluent/plugin/out_forward/connection_manager.rb +113 -0
  216. data/lib/fluent/plugin/out_forward/error.rb +28 -0
  217. data/lib/fluent/plugin/out_forward/failure_detector.rb +84 -0
  218. data/lib/fluent/plugin/out_forward/handshake_protocol.rb +125 -0
  219. data/lib/fluent/plugin/out_forward/load_balancer.rb +114 -0
  220. data/lib/fluent/plugin/out_forward/socket_cache.rb +142 -0
  221. data/lib/fluent/plugin/out_forward.rb +826 -0
  222. data/lib/fluent/plugin/out_http.rb +280 -0
  223. data/lib/fluent/plugin/out_null.rb +74 -0
  224. data/lib/fluent/plugin/out_relabel.rb +32 -0
  225. data/lib/fluent/plugin/out_roundrobin.rb +84 -0
  226. data/lib/fluent/plugin/out_secondary_file.rb +131 -0
  227. data/lib/fluent/plugin/out_stdout.rb +74 -0
  228. data/lib/fluent/plugin/out_stream.rb +130 -0
  229. data/lib/fluent/plugin/output.rb +1566 -0
  230. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  231. data/lib/fluent/plugin/parser.rb +274 -0
  232. data/lib/fluent/plugin/parser_apache.rb +28 -0
  233. data/lib/fluent/plugin/parser_apache2.rb +88 -0
  234. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  235. data/lib/fluent/plugin/parser_csv.rb +114 -0
  236. data/lib/fluent/plugin/parser_json.rb +96 -0
  237. data/lib/fluent/plugin/parser_ltsv.rb +51 -0
  238. data/lib/fluent/plugin/parser_msgpack.rb +50 -0
  239. data/lib/fluent/plugin/parser_multiline.rb +152 -0
  240. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  241. data/lib/fluent/plugin/parser_none.rb +36 -0
  242. data/lib/fluent/plugin/parser_regexp.rb +68 -0
  243. data/lib/fluent/plugin/parser_syslog.rb +496 -0
  244. data/lib/fluent/plugin/parser_tsv.rb +42 -0
  245. data/lib/fluent/plugin/sd_file.rb +156 -0
  246. data/lib/fluent/plugin/sd_srv.rb +135 -0
  247. data/lib/fluent/plugin/sd_static.rb +58 -0
  248. data/lib/fluent/plugin/service_discovery.rb +65 -0
  249. data/lib/fluent/plugin/socket_util.rb +22 -0
  250. data/lib/fluent/plugin/storage.rb +84 -0
  251. data/lib/fluent/plugin/storage_local.rb +162 -0
  252. data/lib/fluent/plugin/string_util.rb +22 -0
  253. data/lib/fluent/plugin.rb +206 -0
  254. data/lib/fluent/plugin_helper/cert_option.rb +191 -0
  255. data/lib/fluent/plugin_helper/child_process.rb +366 -0
  256. data/lib/fluent/plugin_helper/compat_parameters.rb +343 -0
  257. data/lib/fluent/plugin_helper/counter.rb +51 -0
  258. data/lib/fluent/plugin_helper/event_emitter.rb +100 -0
  259. data/lib/fluent/plugin_helper/event_loop.rb +170 -0
  260. data/lib/fluent/plugin_helper/extract.rb +104 -0
  261. data/lib/fluent/plugin_helper/formatter.rb +147 -0
  262. data/lib/fluent/plugin_helper/http_server/app.rb +79 -0
  263. data/lib/fluent/plugin_helper/http_server/compat/server.rb +92 -0
  264. data/lib/fluent/plugin_helper/http_server/compat/ssl_context_extractor.rb +52 -0
  265. data/lib/fluent/plugin_helper/http_server/compat/webrick_handler.rb +58 -0
  266. data/lib/fluent/plugin_helper/http_server/methods.rb +35 -0
  267. data/lib/fluent/plugin_helper/http_server/request.rb +42 -0
  268. data/lib/fluent/plugin_helper/http_server/router.rb +54 -0
  269. data/lib/fluent/plugin_helper/http_server/server.rb +93 -0
  270. data/lib/fluent/plugin_helper/http_server/ssl_context_builder.rb +41 -0
  271. data/lib/fluent/plugin_helper/http_server.rb +135 -0
  272. data/lib/fluent/plugin_helper/inject.rb +154 -0
  273. data/lib/fluent/plugin_helper/metrics.rb +129 -0
  274. data/lib/fluent/plugin_helper/parser.rb +147 -0
  275. data/lib/fluent/plugin_helper/record_accessor.rb +207 -0
  276. data/lib/fluent/plugin_helper/retry_state.rb +219 -0
  277. data/lib/fluent/plugin_helper/server.rb +820 -0
  278. data/lib/fluent/plugin_helper/service_discovery/manager.rb +146 -0
  279. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  280. data/lib/fluent/plugin_helper/service_discovery.rb +125 -0
  281. data/lib/fluent/plugin_helper/socket.rb +288 -0
  282. data/lib/fluent/plugin_helper/socket_option.rb +98 -0
  283. data/lib/fluent/plugin_helper/storage.rb +349 -0
  284. data/lib/fluent/plugin_helper/thread.rb +180 -0
  285. data/lib/fluent/plugin_helper/timer.rb +92 -0
  286. data/lib/fluent/plugin_helper.rb +75 -0
  287. data/lib/fluent/plugin_id.rb +93 -0
  288. data/lib/fluent/process.rb +22 -0
  289. data/lib/fluent/registry.rb +117 -0
  290. data/lib/fluent/root_agent.rb +372 -0
  291. data/lib/fluent/rpc.rb +95 -0
  292. data/lib/fluent/static_config_analysis.rb +194 -0
  293. data/lib/fluent/supervisor.rb +1141 -0
  294. data/lib/fluent/system_config.rb +188 -0
  295. data/lib/fluent/test/base.rb +78 -0
  296. data/lib/fluent/test/driver/base.rb +225 -0
  297. data/lib/fluent/test/driver/base_owned.rb +83 -0
  298. data/lib/fluent/test/driver/base_owner.rb +135 -0
  299. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  300. data/lib/fluent/test/driver/filter.rb +57 -0
  301. data/lib/fluent/test/driver/formatter.rb +30 -0
  302. data/lib/fluent/test/driver/input.rb +31 -0
  303. data/lib/fluent/test/driver/multi_output.rb +53 -0
  304. data/lib/fluent/test/driver/output.rb +102 -0
  305. data/lib/fluent/test/driver/parser.rb +30 -0
  306. data/lib/fluent/test/driver/storage.rb +30 -0
  307. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  308. data/lib/fluent/test/filter_test.rb +77 -0
  309. data/lib/fluent/test/formatter_test.rb +65 -0
  310. data/lib/fluent/test/helpers.rb +134 -0
  311. data/lib/fluent/test/input_test.rb +174 -0
  312. data/lib/fluent/test/log.rb +79 -0
  313. data/lib/fluent/test/output_test.rb +156 -0
  314. data/lib/fluent/test/parser_test.rb +70 -0
  315. data/lib/fluent/test/startup_shutdown.rb +46 -0
  316. data/lib/fluent/test.rb +58 -0
  317. data/lib/fluent/time.rb +512 -0
  318. data/lib/fluent/timezone.rb +171 -0
  319. data/lib/fluent/tls.rb +81 -0
  320. data/lib/fluent/unique_id.rb +39 -0
  321. data/lib/fluent/variable_store.rb +40 -0
  322. data/lib/fluent/version.rb +21 -0
  323. data/lib/fluent/winsvc.rb +105 -0
  324. data/templates/new_gem/Gemfile +3 -0
  325. data/templates/new_gem/README.md.erb +43 -0
  326. data/templates/new_gem/Rakefile +13 -0
  327. data/templates/new_gem/fluent-plugin.gemspec.erb +27 -0
  328. data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
  329. data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
  330. data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
  331. data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
  332. data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
  333. data/templates/new_gem/lib/fluent/plugin/storage.rb.erb +40 -0
  334. data/templates/new_gem/test/helper.rb.erb +8 -0
  335. data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
  336. data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
  337. data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
  338. data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
  339. data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
  340. data/templates/new_gem/test/plugin/test_storage.rb.erb +18 -0
  341. data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
  342. data/templates/plugin_config_formatter/param.md-table.erb +10 -0
  343. data/templates/plugin_config_formatter/param.md.erb +34 -0
  344. data/templates/plugin_config_formatter/section.md.erb +12 -0
  345. data/test/command/test_binlog_reader.rb +362 -0
  346. data/test/command/test_ca_generate.rb +70 -0
  347. data/test/command/test_cap_ctl.rb +100 -0
  348. data/test/command/test_cat.rb +128 -0
  349. data/test/command/test_ctl.rb +56 -0
  350. data/test/command/test_fluentd.rb +1139 -0
  351. data/test/command/test_plugin_config_formatter.rb +398 -0
  352. data/test/command/test_plugin_generator.rb +109 -0
  353. data/test/compat/test_calls_super.rb +166 -0
  354. data/test/compat/test_parser.rb +92 -0
  355. data/test/config/assertions.rb +42 -0
  356. data/test/config/test_config_parser.rb +551 -0
  357. data/test/config/test_configurable.rb +1784 -0
  358. data/test/config/test_configure_proxy.rb +604 -0
  359. data/test/config/test_dsl.rb +415 -0
  360. data/test/config/test_element.rb +518 -0
  361. data/test/config/test_literal_parser.rb +309 -0
  362. data/test/config/test_plugin_configuration.rb +56 -0
  363. data/test/config/test_section.rb +191 -0
  364. data/test/config/test_system_config.rb +201 -0
  365. data/test/config/test_types.rb +408 -0
  366. data/test/counter/test_client.rb +563 -0
  367. data/test/counter/test_error.rb +44 -0
  368. data/test/counter/test_mutex_hash.rb +179 -0
  369. data/test/counter/test_server.rb +589 -0
  370. data/test/counter/test_store.rb +258 -0
  371. data/test/counter/test_validator.rb +137 -0
  372. data/test/helper.rb +155 -0
  373. data/test/helpers/fuzzy_assert.rb +89 -0
  374. data/test/helpers/process_extenstion.rb +33 -0
  375. data/test/plugin/data/2010/01/20100102-030405.log +0 -0
  376. data/test/plugin/data/2010/01/20100102-030406.log +0 -0
  377. data/test/plugin/data/2010/01/20100102.log +0 -0
  378. data/test/plugin/data/log/bar +0 -0
  379. data/test/plugin/data/log/foo/bar.log +0 -0
  380. data/test/plugin/data/log/foo/bar2 +0 -0
  381. data/test/plugin/data/log/test.log +0 -0
  382. data/test/plugin/data/sd_file/config +11 -0
  383. data/test/plugin/data/sd_file/config.json +17 -0
  384. data/test/plugin/data/sd_file/config.yaml +11 -0
  385. data/test/plugin/data/sd_file/config.yml +11 -0
  386. data/test/plugin/data/sd_file/invalid_config.yml +7 -0
  387. data/test/plugin/in_tail/test_fifo.rb +121 -0
  388. data/test/plugin/in_tail/test_io_handler.rb +150 -0
  389. data/test/plugin/in_tail/test_position_file.rb +316 -0
  390. data/test/plugin/out_forward/test_ack_handler.rb +101 -0
  391. data/test/plugin/out_forward/test_connection_manager.rb +145 -0
  392. data/test/plugin/out_forward/test_handshake_protocol.rb +112 -0
  393. data/test/plugin/out_forward/test_load_balancer.rb +106 -0
  394. data/test/plugin/out_forward/test_socket_cache.rb +174 -0
  395. data/test/plugin/test_bare_output.rb +131 -0
  396. data/test/plugin/test_base.rb +115 -0
  397. data/test/plugin/test_buf_file.rb +1275 -0
  398. data/test/plugin/test_buf_file_single.rb +833 -0
  399. data/test/plugin/test_buf_memory.rb +42 -0
  400. data/test/plugin/test_buffer.rb +1383 -0
  401. data/test/plugin/test_buffer_chunk.rb +198 -0
  402. data/test/plugin/test_buffer_file_chunk.rb +871 -0
  403. data/test/plugin/test_buffer_file_single_chunk.rb +611 -0
  404. data/test/plugin/test_buffer_memory_chunk.rb +339 -0
  405. data/test/plugin/test_compressable.rb +87 -0
  406. data/test/plugin/test_file_util.rb +96 -0
  407. data/test/plugin/test_file_wrapper.rb +58 -0
  408. data/test/plugin/test_filter.rb +368 -0
  409. data/test/plugin/test_filter_grep.rb +697 -0
  410. data/test/plugin/test_filter_parser.rb +731 -0
  411. data/test/plugin/test_filter_record_transformer.rb +577 -0
  412. data/test/plugin/test_filter_stdout.rb +207 -0
  413. data/test/plugin/test_formatter_csv.rb +136 -0
  414. data/test/plugin/test_formatter_hash.rb +38 -0
  415. data/test/plugin/test_formatter_json.rb +61 -0
  416. data/test/plugin/test_formatter_ltsv.rb +70 -0
  417. data/test/plugin/test_formatter_msgpack.rb +28 -0
  418. data/test/plugin/test_formatter_out_file.rb +116 -0
  419. data/test/plugin/test_formatter_single_value.rb +44 -0
  420. data/test/plugin/test_formatter_tsv.rb +76 -0
  421. data/test/plugin/test_in_debug_agent.rb +49 -0
  422. data/test/plugin/test_in_exec.rb +261 -0
  423. data/test/plugin/test_in_forward.rb +1178 -0
  424. data/test/plugin/test_in_gc_stat.rb +62 -0
  425. data/test/plugin/test_in_http.rb +1103 -0
  426. data/test/plugin/test_in_monitor_agent.rb +923 -0
  427. data/test/plugin/test_in_object_space.rb +66 -0
  428. data/test/plugin/test_in_sample.rb +190 -0
  429. data/test/plugin/test_in_syslog.rb +505 -0
  430. data/test/plugin/test_in_tail.rb +2639 -0
  431. data/test/plugin/test_in_tcp.rb +243 -0
  432. data/test/plugin/test_in_udp.rb +268 -0
  433. data/test/plugin/test_in_unix.rb +181 -0
  434. data/test/plugin/test_input.rb +137 -0
  435. data/test/plugin/test_metadata.rb +89 -0
  436. data/test/plugin/test_metrics.rb +294 -0
  437. data/test/plugin/test_metrics_local.rb +96 -0
  438. data/test/plugin/test_multi_output.rb +204 -0
  439. data/test/plugin/test_out_copy.rb +308 -0
  440. data/test/plugin/test_out_exec.rb +312 -0
  441. data/test/plugin/test_out_exec_filter.rb +606 -0
  442. data/test/plugin/test_out_file.rb +1037 -0
  443. data/test/plugin/test_out_forward.rb +1358 -0
  444. data/test/plugin/test_out_http.rb +428 -0
  445. data/test/plugin/test_out_null.rb +105 -0
  446. data/test/plugin/test_out_relabel.rb +28 -0
  447. data/test/plugin/test_out_roundrobin.rb +146 -0
  448. data/test/plugin/test_out_secondary_file.rb +458 -0
  449. data/test/plugin/test_out_stdout.rb +205 -0
  450. data/test/plugin/test_out_stream.rb +103 -0
  451. data/test/plugin/test_output.rb +1065 -0
  452. data/test/plugin/test_output_as_buffered.rb +2024 -0
  453. data/test/plugin/test_output_as_buffered_backup.rb +363 -0
  454. data/test/plugin/test_output_as_buffered_compress.rb +165 -0
  455. data/test/plugin/test_output_as_buffered_overflow.rb +250 -0
  456. data/test/plugin/test_output_as_buffered_retries.rb +966 -0
  457. data/test/plugin/test_output_as_buffered_secondary.rb +882 -0
  458. data/test/plugin/test_output_as_standard.rb +374 -0
  459. data/test/plugin/test_owned_by.rb +35 -0
  460. data/test/plugin/test_parser.rb +399 -0
  461. data/test/plugin/test_parser_apache.rb +42 -0
  462. data/test/plugin/test_parser_apache2.rb +47 -0
  463. data/test/plugin/test_parser_apache_error.rb +45 -0
  464. data/test/plugin/test_parser_csv.rb +200 -0
  465. data/test/plugin/test_parser_json.rb +138 -0
  466. data/test/plugin/test_parser_labeled_tsv.rb +160 -0
  467. data/test/plugin/test_parser_multiline.rb +111 -0
  468. data/test/plugin/test_parser_nginx.rb +88 -0
  469. data/test/plugin/test_parser_none.rb +52 -0
  470. data/test/plugin/test_parser_regexp.rb +289 -0
  471. data/test/plugin/test_parser_syslog.rb +650 -0
  472. data/test/plugin/test_parser_tsv.rb +122 -0
  473. data/test/plugin/test_sd_file.rb +228 -0
  474. data/test/plugin/test_sd_srv.rb +230 -0
  475. data/test/plugin/test_storage.rb +167 -0
  476. data/test/plugin/test_storage_local.rb +335 -0
  477. data/test/plugin/test_string_util.rb +26 -0
  478. data/test/plugin_helper/data/cert/cert-key.pem +27 -0
  479. data/test/plugin_helper/data/cert/cert-with-CRLF.pem +19 -0
  480. data/test/plugin_helper/data/cert/cert-with-no-newline.pem +19 -0
  481. data/test/plugin_helper/data/cert/cert.pem +19 -0
  482. data/test/plugin_helper/data/cert/cert_chains/ca-cert-key.pem +27 -0
  483. data/test/plugin_helper/data/cert/cert_chains/ca-cert.pem +20 -0
  484. data/test/plugin_helper/data/cert/cert_chains/cert-key.pem +27 -0
  485. data/test/plugin_helper/data/cert/cert_chains/cert.pem +40 -0
  486. data/test/plugin_helper/data/cert/empty.pem +0 -0
  487. data/test/plugin_helper/data/cert/generate_cert.rb +125 -0
  488. data/test/plugin_helper/data/cert/with_ca/ca-cert-key-pass.pem +30 -0
  489. data/test/plugin_helper/data/cert/with_ca/ca-cert-key.pem +27 -0
  490. data/test/plugin_helper/data/cert/with_ca/ca-cert-pass.pem +20 -0
  491. data/test/plugin_helper/data/cert/with_ca/ca-cert.pem +20 -0
  492. data/test/plugin_helper/data/cert/with_ca/cert-key-pass.pem +30 -0
  493. data/test/plugin_helper/data/cert/with_ca/cert-key.pem +27 -0
  494. data/test/plugin_helper/data/cert/with_ca/cert-pass.pem +21 -0
  495. data/test/plugin_helper/data/cert/with_ca/cert.pem +21 -0
  496. data/test/plugin_helper/data/cert/without_ca/cert-key-pass.pem +30 -0
  497. data/test/plugin_helper/data/cert/without_ca/cert-key.pem +27 -0
  498. data/test/plugin_helper/data/cert/without_ca/cert-pass.pem +20 -0
  499. data/test/plugin_helper/data/cert/without_ca/cert.pem +20 -0
  500. data/test/plugin_helper/http_server/test_app.rb +65 -0
  501. data/test/plugin_helper/http_server/test_route.rb +32 -0
  502. data/test/plugin_helper/service_discovery/test_manager.rb +93 -0
  503. data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +21 -0
  504. data/test/plugin_helper/test_cert_option.rb +25 -0
  505. data/test/plugin_helper/test_child_process.rb +852 -0
  506. data/test/plugin_helper/test_compat_parameters.rb +358 -0
  507. data/test/plugin_helper/test_event_emitter.rb +80 -0
  508. data/test/plugin_helper/test_event_loop.rb +52 -0
  509. data/test/plugin_helper/test_extract.rb +194 -0
  510. data/test/plugin_helper/test_formatter.rb +255 -0
  511. data/test/plugin_helper/test_http_server_helper.rb +372 -0
  512. data/test/plugin_helper/test_inject.rb +561 -0
  513. data/test/plugin_helper/test_metrics.rb +137 -0
  514. data/test/plugin_helper/test_parser.rb +264 -0
  515. data/test/plugin_helper/test_record_accessor.rb +238 -0
  516. data/test/plugin_helper/test_retry_state.rb +1006 -0
  517. data/test/plugin_helper/test_server.rb +1841 -0
  518. data/test/plugin_helper/test_service_discovery.rb +165 -0
  519. data/test/plugin_helper/test_socket.rb +146 -0
  520. data/test/plugin_helper/test_storage.rb +542 -0
  521. data/test/plugin_helper/test_thread.rb +164 -0
  522. data/test/plugin_helper/test_timer.rb +130 -0
  523. data/test/scripts/exec_script.rb +32 -0
  524. data/test/scripts/fluent/plugin/formatter1/formatter_test1.rb +7 -0
  525. data/test/scripts/fluent/plugin/formatter2/formatter_test2.rb +7 -0
  526. data/test/scripts/fluent/plugin/formatter_known.rb +8 -0
  527. data/test/scripts/fluent/plugin/out_test.rb +81 -0
  528. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  529. data/test/scripts/fluent/plugin/parser_known.rb +4 -0
  530. data/test/test_capability.rb +74 -0
  531. data/test/test_clock.rb +164 -0
  532. data/test/test_config.rb +333 -0
  533. data/test/test_configdsl.rb +148 -0
  534. data/test/test_daemonizer.rb +91 -0
  535. data/test/test_engine.rb +203 -0
  536. data/test/test_event.rb +531 -0
  537. data/test/test_event_router.rb +348 -0
  538. data/test/test_event_time.rb +199 -0
  539. data/test/test_filter.rb +121 -0
  540. data/test/test_fluent_log_event_router.rb +99 -0
  541. data/test/test_formatter.rb +366 -0
  542. data/test/test_input.rb +31 -0
  543. data/test/test_log.rb +994 -0
  544. data/test/test_logger_initializer.rb +46 -0
  545. data/test/test_match.rb +148 -0
  546. data/test/test_mixin.rb +351 -0
  547. data/test/test_msgpack_factory.rb +18 -0
  548. data/test/test_oj_options.rb +55 -0
  549. data/test/test_output.rb +278 -0
  550. data/test/test_plugin.rb +251 -0
  551. data/test/test_plugin_classes.rb +370 -0
  552. data/test/test_plugin_helper.rb +81 -0
  553. data/test/test_plugin_id.rb +119 -0
  554. data/test/test_process.rb +14 -0
  555. data/test/test_root_agent.rb +951 -0
  556. data/test/test_static_config_analysis.rb +177 -0
  557. data/test/test_supervisor.rb +791 -0
  558. data/test/test_test_drivers.rb +136 -0
  559. data/test/test_time_formatter.rb +301 -0
  560. data/test/test_time_parser.rb +362 -0
  561. data/test/test_tls.rb +65 -0
  562. data/test/test_unique_id.rb +47 -0
  563. data/test/test_variable_store.rb +65 -0
  564. metadata +1191 -0
@@ -0,0 +1,1841 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin_helper/server'
3
+ require 'fluent/plugin_helper/cert_option' # to create certs for tests
4
+ require 'fluent/plugin/base'
5
+ require 'timeout'
6
+
7
+ require 'serverengine'
8
+ require 'fileutils'
9
+
10
+ class ServerPluginHelperTest < Test::Unit::TestCase
11
+ class Dummy < Fluent::Plugin::TestBase
12
+ helpers :server
13
+ end
14
+
15
+ TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/../tmp/plugin_helper_server")
16
+
17
+ setup do
18
+ @port = unused_port
19
+ @socket_manager_path = ServerEngine::SocketManager::Server.generate_path
20
+ if @socket_manager_path.is_a?(String) && File.exist?(@socket_manager_path)
21
+ FileUtils.rm_f @socket_manager_path
22
+ end
23
+ @socket_manager_server = ServerEngine::SocketManager::Server.open(@socket_manager_path)
24
+ ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = @socket_manager_path.to_s
25
+
26
+ @d = Dummy.new
27
+ @d.start
28
+ @d.after_start
29
+ end
30
+
31
+ teardown do
32
+ (@d.stopped? || @d.stop) rescue nil
33
+ (@d.before_shutdown? || @d.before_shutdown) rescue nil
34
+ (@d.shutdown? || @d.shutdown) rescue nil
35
+ (@d.after_shutdown? || @d.after_shutdown) rescue nil
36
+ (@d.closed? || @d.close) rescue nil
37
+ (@d.terminated? || @d.terminate) rescue nil
38
+
39
+ @socket_manager_server.close
40
+ if @socket_manager_server.is_a?(String) && File.exist?(@socket_manager_path)
41
+ FileUtils.rm_f @socket_manager_path
42
+ end
43
+ end
44
+
45
+ sub_test_case 'plugin instance' do
46
+ test 'can be instantiated to be able to create threads' do
47
+ d = Dummy.new
48
+ assert d.respond_to?(:_servers)
49
+ assert d._servers.empty?
50
+
51
+ assert d.respond_to?(:server_wait_until_start)
52
+ assert d.respond_to?(:server_wait_until_stop)
53
+ assert d.respond_to?(:server_create_connection)
54
+ assert d.respond_to?(:server_create)
55
+ assert d.respond_to?(:server_create_tcp)
56
+ assert d.respond_to?(:server_create_udp)
57
+ assert d.respond_to?(:server_create_tls)
58
+ end
59
+
60
+ test 'can be configured' do
61
+ d = Dummy.new
62
+ assert_nothing_raised do
63
+ d.configure(config_element())
64
+ end
65
+ assert d.plugin_id
66
+ assert d.log
67
+ assert_equal 0, d.transport_config.linger_timeout
68
+ end
69
+
70
+ test 'can change linger_timeout option' do
71
+ d = Dummy.new
72
+
73
+ transport_opts = {
74
+ 'linger_timeout' => 1,
75
+ }
76
+ transport_conf = config_element('transport', 'tcp', transport_opts)
77
+ conf = config_element('source', 'tag.*', {}, [transport_conf])
78
+
79
+ assert_nothing_raised do
80
+ d.configure(conf)
81
+ end
82
+ assert d.plugin_id
83
+ assert d.log
84
+ assert_equal 1, d.transport_config.linger_timeout
85
+ end
86
+ end
87
+
88
+ # run tests for tcp, udp, tls and unix
89
+ sub_test_case '#server_create and #server_create_connection' do
90
+ methods = {server_create: :server_create, server_create_connection: :server_create_connection}
91
+
92
+ data(methods)
93
+ test 'raise error if title is not specified or not a symbol' do |m|
94
+ assert_raise(ArgumentError.new("BUG: title must be a symbol")) do
95
+ @d.__send__(m, nil, @port){|x| x }
96
+ end
97
+ assert_raise(ArgumentError.new("BUG: title must be a symbol")) do
98
+ @d.__send__(m, "", @port){|x| x }
99
+ end
100
+ assert_raise(ArgumentError.new("BUG: title must be a symbol")) do
101
+ @d.__send__(m, "title", @port){|x| x }
102
+ end
103
+ assert_nothing_raised do
104
+ @d.__send__(m, :myserver, @port){|x| x }
105
+ end
106
+ end
107
+
108
+ data(methods)
109
+ test 'raise error if port is not specified or not an integer' do |m|
110
+ assert_raise(ArgumentError.new("BUG: port must be an integer")) do
111
+ @d.__send__(m, :myserver, nil){|x| x }
112
+ end
113
+ assert_raise(ArgumentError.new("BUG: port must be an integer")) do
114
+ @d.__send__(m, :myserver, "1"){|x| x }
115
+ end
116
+ assert_raise(ArgumentError.new("BUG: port must be an integer")) do
117
+ @d.__send__(m, :myserver, 1.5){|x| x }
118
+ end
119
+ assert_nothing_raised do
120
+ @d.__send__(m, :myserver, @port){|x| x }
121
+ end
122
+ end
123
+
124
+ data(methods)
125
+ test 'raise error if block is not specified' do |m|
126
+ assert_raise(ArgumentError) do
127
+ @d.__send__(m, :myserver, @port)
128
+ end
129
+ assert_nothing_raised do
130
+ @d.__send__(m, :myserver, @port){|x| x }
131
+ end
132
+ end
133
+
134
+ data(methods)
135
+ test 'creates tcp server, binds 0.0.0.0 in default' do |m|
136
+ @d.__send__(m, :myserver, @port){|x| x }
137
+
138
+ assert_equal 1, @d._servers.size
139
+
140
+ created_server_info = @d._servers.first
141
+
142
+ assert_equal :myserver, created_server_info.title
143
+ assert_equal @port, created_server_info.port
144
+
145
+ assert_equal :tcp, created_server_info.proto
146
+ assert_equal "0.0.0.0", created_server_info.bind
147
+
148
+ created_server = created_server_info.server
149
+
150
+ assert created_server.is_a?(Coolio::TCPServer)
151
+ assert_equal "0.0.0.0", created_server.instance_eval{ @listen_socket }.addr[3]
152
+ end
153
+
154
+ data(methods)
155
+ test 'creates tcp server if specified in proto' do |m|
156
+ @d.__send__(m, :myserver, @port, proto: :tcp){|x| x }
157
+
158
+ created_server_info = @d._servers.first
159
+ assert_equal :tcp, created_server_info.proto
160
+ created_server = created_server_info.server
161
+ assert created_server.is_a?(Coolio::TCPServer)
162
+ end
163
+
164
+ data(methods)
165
+ test 'creates tls server in default if transport section and tcp protocol specified' do |m|
166
+ @d = d = Dummy.new
167
+ transport_conf = config_element('transport', 'tcp', {}, [])
168
+ d.configure(config_element('ROOT', '', {}, [transport_conf]))
169
+ d.start
170
+ d.after_start
171
+
172
+ d.__send__(m, :myserver, @port){|x| x }
173
+
174
+ created_server_info = @d._servers.first
175
+ assert_equal :tcp, created_server_info.proto
176
+ created_server = created_server_info.server
177
+ assert created_server.is_a?(Coolio::TCPServer)
178
+ end
179
+
180
+ data(methods)
181
+ test 'creates tls server if specified in proto' do |m|
182
+ assert_raise(ArgumentError.new("BUG: TLS transport specified, but certification options are not specified")) do
183
+ @d.__send__(m, :myserver, @port, proto: :tls){|x| x }
184
+ end
185
+ @d.__send__(m, :myserver, @port, proto: :tls, tls_options: {insecure: true}){|x| x }
186
+
187
+ created_server_info = @d._servers.first
188
+ assert_equal :tls, created_server_info.proto
189
+ created_server = created_server_info.server
190
+ assert created_server.is_a?(Coolio::TCPServer) # yes, TCP here
191
+ end
192
+
193
+ data(methods)
194
+ test 'creates tls server in default if transport section and tls protocol specified' do |m|
195
+ @d = d = Dummy.new
196
+ transport_conf = config_element('transport', 'tls', {'insecure' => 'true'}, [])
197
+ d.configure(config_element('ROOT', '', {}, [transport_conf]))
198
+ d.start
199
+ d.after_start
200
+
201
+ d.__send__(m, :myserver, @port){|x| x }
202
+
203
+ created_server_info = @d._servers.first
204
+ assert_equal :tls, created_server_info.proto
205
+ created_server = created_server_info.server
206
+ assert created_server.is_a?(Coolio::TCPServer) # OK, it's Coolio::TCPServer
207
+ end
208
+
209
+ data(methods)
210
+ test 'creates unix server if specified in proto' do |m|
211
+ # pend "not implemented yet"
212
+ end
213
+
214
+ data(methods)
215
+ test 'raise error if unknown protocol specified' do |m|
216
+ assert_raise(ArgumentError.new("BUG: invalid protocol name")) do
217
+ @d.__send__(m, :myserver, @port, proto: :quic){|x| x }
218
+ end
219
+ end
220
+
221
+ data(
222
+ 'server_create tcp' => [:server_create, :tcp],
223
+ 'server_create tls' => [:server_create, :tls],
224
+ # 'server_create unix' => [:server_create, :unix],
225
+ 'server_create_connection tcp' => [:server_create_connection, :tcp],
226
+ 'server_create_connection tls' => [:server_create_connection, :tls],
227
+ # 'server_create_connection tcp' => [:server_create_connection, :unix],
228
+ )
229
+ test 'raise error if udp options specified for tcp/tls/unix' do |(m, proto)|
230
+ assert_raise ArgumentError do
231
+ @d.__send__(m, :myserver, @port, proto: proto, max_bytes: 128){|x| x }
232
+ end
233
+ assert_raise ArgumentError do
234
+ @d.__send__(m, :myserver, @port, proto: proto, flags: 1){|x| x }
235
+ end
236
+ end
237
+
238
+ data(
239
+ 'server_create udp' => [:server_create, :udp],
240
+ )
241
+ test 'raise error if tcp/tls options specified for udp' do |(m, proto)|
242
+ assert_raise(ArgumentError.new("BUG: linger_timeout is available for tcp/tls")) do
243
+ @d.__send__(m, :myserver, @port, proto: proto, linger_timeout: 1, max_bytes: 128){|x| x }
244
+ end
245
+ end
246
+
247
+ data(
248
+ 'server_create udp' => [:server_create, :udp],
249
+ )
250
+ test 'raise error if tcp/tls/unix backlog options specified for udp' do |(m, proto)|
251
+ assert_raise(ArgumentError.new("BUG: backlog is available for tcp/tls")) do
252
+ @d.__send__(m, :myserver, @port, proto: proto, backlog: 500){|x| x }
253
+ end
254
+ end
255
+
256
+ data(
257
+ 'server_create udp' => [:server_create, :udp],
258
+ )
259
+ test 'raise error if tcp/tls send_keepalive_packet option is specified for udp' do |(m, proto)|
260
+ assert_raise(ArgumentError.new("BUG: send_keepalive_packet is available for tcp/tls")) do
261
+ @d.__send__(m, :myserver, @port, proto: proto, send_keepalive_packet: true){|x| x }
262
+ end
263
+ end
264
+
265
+ data(
266
+ 'server_create tcp' => [:server_create, :tcp, {}],
267
+ 'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
268
+ # 'server_create unix' => [:server_create, :unix, {}],
269
+ 'server_create_connection tcp' => [:server_create_connection, :tcp, {}],
270
+ # 'server_create_connection unix' => [:server_create_connection, :unix, {}],
271
+ )
272
+ test 'raise error if tls options specified for tcp/udp/unix' do |(m, proto, kwargs)|
273
+ assert_raise(ArgumentError.new("BUG: tls_options is available only for tls")) do
274
+ @d.__send__(m, :myserver, @port, proto: proto, tls_options: {}, **kwargs){|x| x }
275
+ end
276
+ end
277
+
278
+ data(
279
+ 'server_create tcp' => [:server_create, :tcp, {}],
280
+ 'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
281
+ 'server_create tls' => [:server_create, :tls, {tls_options: {insecure: true}}],
282
+ 'server_create_connection tcp' => [:server_create_connection, :tcp, {}],
283
+ 'server_create_connection tls' => [:server_create_connection, :tls, {tls_options: {insecure: true}}],
284
+ )
285
+ test 'can bind specified IPv4 address' do |(m, proto, kwargs)|
286
+ @d.__send__(m, :myserver, @port, proto: proto, bind: "127.0.0.1", **kwargs){|x| x }
287
+ assert_equal "127.0.0.1", @d._servers.first.bind
288
+ assert_equal "127.0.0.1", @d._servers.first.server.instance_eval{ instance_variable_defined?(:@listen_socket) ? @listen_socket : @_io }.addr[3]
289
+ end
290
+
291
+ data(
292
+ 'server_create tcp' => [:server_create, :tcp, {}],
293
+ 'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
294
+ 'server_create tls' => [:server_create, :tls, {tls_options: {insecure: true}}],
295
+ 'server_create_connection tcp' => [:server_create_connection, :tcp, {}],
296
+ 'server_create_connection tls' => [:server_create_connection, :tls, {tls_options: {insecure: true}}],
297
+ )
298
+ test 'can bind specified IPv6 address' do |(m, proto, kwargs)| # if available
299
+ omit "IPv6 unavailable here" unless ipv6_enabled?
300
+ @d.__send__(m, :myserver, @port, proto: proto, bind: "::1", **kwargs){|x| x }
301
+ assert_equal "::1", @d._servers.first.bind
302
+ assert_equal "::1", @d._servers.first.server.instance_eval{ instance_variable_defined?(:@listen_socket) ? @listen_socket : @_io }.addr[3]
303
+ end
304
+
305
+ data(
306
+ 'server_create tcp' => [:server_create, :tcp, {}],
307
+ 'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
308
+ 'server_create tls' => [:server_create, :tls, {tls_options: {insecure: true}}],
309
+ # 'server_create unix' => [:server_create, :unix, {}],
310
+ 'server_create_connection tcp' => [:server_create, :tcp, {}],
311
+ 'server_create_connection tls' => [:server_create, :tls, {tls_options: {insecure: true}}],
312
+ # 'server_create_connection unix' => [:server_create, :unix, {}],
313
+ )
314
+ test 'can create 2 or more servers which share same bind address and port if shared option is true' do |(m, proto, kwargs)|
315
+ begin
316
+ d2 = Dummy.new; d2.start; d2.after_start
317
+
318
+ assert_nothing_raised do
319
+ @d.__send__(m, :myserver, @port, proto: proto, **kwargs){|x| x }
320
+ d2.__send__(m, :myserver, @port, proto: proto, **kwargs){|x| x }
321
+ end
322
+ ensure
323
+ d2.stop; d2.before_shutdown; d2.shutdown; d2.after_shutdown; d2.close; d2.terminate
324
+ end
325
+ end
326
+
327
+ data(
328
+ 'server_create tcp' => [:server_create, :tcp, {}],
329
+ # Disable udp test because the behaviour of SO_REUSEXXX option is different betweeen BSD, Linux and others...
330
+ # Need to find good way for testing on local, CI service and others.
331
+ #'server_create udp' => [:server_create, :udp, {max_bytes: 128}],
332
+ 'server_create tls' => [:server_create, :tls, {tls_options: {insecure: true}}],
333
+ # 'server_create unix' => [:server_create, :unix, {}],
334
+ 'server_create_connection tcp' => [:server_create, :tcp, {}],
335
+ 'server_create_connection tls' => [:server_create, :tls, {tls_options: {insecure: true}}],
336
+ # 'server_create_connection unix' => [:server_create, :unix, {}],
337
+ )
338
+ test 'cannot create 2 or more servers using same bind address and port if shared option is false' do |(m, proto, kwargs)|
339
+ begin
340
+ d2 = Dummy.new; d2.start; d2.after_start
341
+
342
+ assert_nothing_raised do
343
+ @d.__send__(m, :myserver, @port, proto: proto, shared: false, **kwargs){|x| x }
344
+ end
345
+ assert_raise(Errno::EADDRINUSE, Errno::EACCES) do
346
+ d2.__send__(m, :myserver, @port, proto: proto, **kwargs){|x| x }
347
+ end
348
+ ensure
349
+ d2.stop; d2.before_shutdown; d2.shutdown; d2.after_shutdown; d2.close; d2.terminate
350
+ end
351
+ end
352
+ end
353
+
354
+ sub_test_case '#server_create' do
355
+ data(
356
+ 'tcp' => [:tcp, {}],
357
+ 'udp' => [:udp, {max_bytes: 128}],
358
+ 'tls' => [:tls, {tls_options: {insecure: true}}],
359
+ # 'unix' => [:unix, {}],
360
+ )
361
+ test 'raise error if block argument is not specified or too many' do |(proto, kwargs)|
362
+ assert_raise(ArgumentError.new("BUG: block must have 1 or 2 arguments")) do
363
+ @d.server_create(:myserver, @port, proto: proto, **kwargs){ 1 }
364
+ end
365
+ assert_raise(ArgumentError.new("BUG: block must have 1 or 2 arguments")) do
366
+ @d.server_create(:myserver, @port, proto: proto, **kwargs){|sock, conn, what_is_this| 1 }
367
+ end
368
+ end
369
+
370
+ test 'creates udp server if specified in proto' do
371
+ @d.server_create(:myserver, @port, proto: :udp, max_bytes: 512){|x| x }
372
+
373
+ created_server_info = @d._servers.first
374
+ assert_equal :udp, created_server_info.proto
375
+ created_server = created_server_info.server
376
+ assert created_server.is_a?(Fluent::PluginHelper::Server::EventHandler::UDPServer)
377
+ end
378
+ end
379
+
380
+ sub_test_case '#server_create_tcp' do
381
+ test 'can accept all keyword arguments valid for tcp server' do
382
+ assert_nothing_raised do
383
+ @d.server_create_tcp(:s, @port, bind: '127.0.0.1', shared: false, resolve_name: true, linger_timeout: 10, backlog: 500, send_keepalive_packet: true) do |data, conn|
384
+ # ...
385
+ end
386
+ end
387
+ end
388
+
389
+ test 'creates a tcp server just to read data' do
390
+ received = ""
391
+ @d.server_create_tcp(:s, @port) do |data|
392
+ received << data
393
+ end
394
+ 3.times do
395
+ sock = TCPSocket.new("127.0.0.1", @port)
396
+ sock.puts "yay"
397
+ sock.puts "foo"
398
+ sock.close
399
+ end
400
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
401
+ assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
402
+ end
403
+
404
+ test 'creates a tcp server to read and write data' do
405
+ received = ""
406
+ responses = []
407
+ @d.server_create_tcp(:s, @port) do |data, conn|
408
+ received << data
409
+ conn.write "ack\n"
410
+ end
411
+ 3.times do
412
+ TCPSocket.open("127.0.0.1", @port) do |sock|
413
+ sock.puts "yay"
414
+ sock.puts "foo"
415
+ responses << sock.readline
416
+ end
417
+ end
418
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
419
+ assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
420
+ assert_equal ["ack\n","ack\n","ack\n"], responses
421
+ end
422
+
423
+ test 'creates a tcp server to read and write data using IPv6' do
424
+ omit "IPv6 unavailable here" unless ipv6_enabled?
425
+
426
+ received = ""
427
+ responses = []
428
+ @d.server_create_tcp(:s, @port, bind: "::1") do |data, conn|
429
+ received << data
430
+ conn.write "ack\n"
431
+ end
432
+ 3.times do
433
+ TCPSocket.open("::1", @port) do |sock|
434
+ sock.puts "yay"
435
+ sock.puts "foo"
436
+ responses << sock.readline
437
+ end
438
+ end
439
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
440
+ assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
441
+ assert_equal ["ack\n","ack\n","ack\n"], responses
442
+ end
443
+
444
+ test 'does not resolve name of client address in default' do
445
+ received = ""
446
+ sources = []
447
+ @d.server_create_tcp(:s, @port) do |data, conn|
448
+ received << data
449
+ sources << conn.remote_host
450
+ end
451
+ 3.times do
452
+ TCPSocket.open("127.0.0.1", @port) do |sock|
453
+ sock.puts "yay"
454
+ end
455
+ end
456
+ waiting(10){ sleep 0.1 until received.bytesize == 12 }
457
+ assert_equal "yay\nyay\nyay\n", received
458
+ assert{ sources.all?{|s| s == "127.0.0.1" } }
459
+ end
460
+
461
+ test 'does resolve name of client address if resolve_name is true' do
462
+ hostname = Socket.getnameinfo([nil, nil, nil, "127.0.0.1"])[0]
463
+
464
+ received = ""
465
+ sources = []
466
+ @d.server_create_tcp(:s, @port, resolve_name: true) do |data, conn|
467
+ received << data
468
+ sources << conn.remote_host
469
+ end
470
+ 3.times do
471
+ TCPSocket.open("127.0.0.1", @port) do |sock|
472
+ sock.puts "yay"
473
+ end
474
+ end
475
+ waiting(10){ sleep 0.1 until received.bytesize == 12 }
476
+ assert_equal "yay\nyay\nyay\n", received
477
+ assert{ sources.all?{|s| s == hostname } }
478
+ end
479
+
480
+ test 'can keep connections alive for tcp if keepalive specified' do
481
+ # pend "not implemented yet"
482
+ end
483
+
484
+ test 'raises error if plugin registers data callback for connection object from #server_create' do
485
+ received = ""
486
+ errors = []
487
+ @d.server_create_tcp(:s, @port) do |data, conn|
488
+ received << data
489
+ begin
490
+ conn.data{|d| received << d.upcase }
491
+ rescue => e
492
+ errors << e
493
+ end
494
+ end
495
+ TCPSocket.open("127.0.0.1", @port) do |sock|
496
+ sock.puts "foo"
497
+ end
498
+ waiting(10){ sleep 0.1 until received.bytesize == 4 || errors.size == 1 }
499
+ assert_equal "foo\n", received
500
+ assert{ errors.size > 0 } # it might be called twice (or more) when connection was accepted, and then data arrived (or more)
501
+ assert_equal "data callback can be registered just once, but registered twice", errors.first.message
502
+ end
503
+
504
+ test 'can call write_complete callback if registered' do
505
+ buffer = ""
506
+ lines = []
507
+ responses = []
508
+ response_completes = []
509
+ @d.server_create_tcp(:s, @port) do |data, conn|
510
+ conn.on(:write_complete){|c| response_completes << true }
511
+ buffer << data
512
+ if idx = buffer.index("\n")
513
+ lines << buffer.slice!(0,idx+1)
514
+ conn.write "ack\n"
515
+ end
516
+ end
517
+ 3.times do
518
+ TCPSocket.open("127.0.0.1", @port) do |sock|
519
+ sock.write "yay"
520
+ sock.write "foo\n"
521
+ begin
522
+ responses << sock.readline
523
+ rescue EOFError, IOError, Errno::ECONNRESET
524
+ # ignore
525
+ end
526
+ sock.close
527
+ end
528
+ end
529
+ waiting(10){ sleep 0.1 until lines.size == 3 && response_completes.size == 3 }
530
+ assert_equal ["yayfoo\n", "yayfoo\n", "yayfoo\n"], lines
531
+ assert_equal ["ack\n","ack\n","ack\n"], responses
532
+ assert_equal [true, true, true], response_completes
533
+ end
534
+
535
+ test 'can call close callback if registered' do
536
+ buffer = ""
537
+ lines = []
538
+ callback_results = []
539
+ @d.server_create_tcp(:s, @port) do |data, conn|
540
+ conn.on(:close){|c| callback_results << "closed" }
541
+ buffer << data
542
+ if idx = buffer.index("\n")
543
+ lines << buffer.slice!(0,idx+1)
544
+ conn.write "ack\n"
545
+ end
546
+ end
547
+ 3.times do
548
+ TCPSocket.open("127.0.0.1", @port) do |sock|
549
+ sock.write "yay"
550
+ sock.write "foo\n"
551
+ begin
552
+ while line = sock.readline
553
+ if line == "ack\n"
554
+ sock.close
555
+ end
556
+ end
557
+ rescue EOFError, IOError, Errno::ECONNRESET
558
+ # ignore
559
+ end
560
+ end
561
+ end
562
+ waiting(10){ sleep 0.1 until lines.size == 3 && callback_results.size == 3 }
563
+ assert_equal ["yayfoo\n", "yayfoo\n", "yayfoo\n"], lines
564
+ assert_equal ["closed", "closed", "closed"], callback_results
565
+ end
566
+
567
+ test 'can listen IPv4 / IPv6 together' do
568
+ omit "IPv6 unavailable here" unless ipv6_enabled?
569
+
570
+ assert_nothing_raised do
571
+ @d.server_create_tcp(:s_ipv4, @port, bind: '0.0.0.0', shared: false) do |data, conn|
572
+ # ...
573
+ end
574
+ @d.server_create_tcp(:s_ipv6, @port, bind: '::', shared: false) do |data, conn|
575
+ # ...
576
+ end
577
+ end
578
+ end
579
+ end
580
+
581
+ sub_test_case '#server_create_udp' do
582
+ test 'can accept all keyword arguments valid for udp server' do
583
+ assert_nothing_raised do
584
+ @d.server_create_udp(:s, @port, bind: '127.0.0.1', shared: false, resolve_name: true, max_bytes: 100, flags: 1) do |data, conn|
585
+ # ...
586
+ end
587
+ end
588
+ end
589
+
590
+ test 'creates a udp server just to read data' do
591
+ received = ""
592
+ @d.server_create_udp(:s, @port, max_bytes: 128) do |data|
593
+ received << data
594
+ end
595
+ bind_port = unused_port(protocol: :udp, bind: "127.0.0.1")
596
+ 3.times do
597
+ sock = UDPSocket.new(Socket::AF_INET)
598
+ sock.bind("127.0.0.1", bind_port)
599
+ sock.connect("127.0.0.1", @port)
600
+ sock.puts "yay"
601
+ sock.puts "foo"
602
+ sock.close
603
+ end
604
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
605
+ assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
606
+ end
607
+
608
+ test 'creates a udp server to read and write data' do
609
+ received = ""
610
+ responses = []
611
+ @d.server_create_udp(:s, @port, max_bytes: 128) do |data, sock|
612
+ received << data
613
+ sock.write "ack\n"
614
+ end
615
+ bind_port = unused_port
616
+ 3.times do
617
+ begin
618
+ sock = UDPSocket.new(Socket::AF_INET)
619
+ sock.bind("127.0.0.1", bind_port)
620
+ sock.connect("127.0.0.1", @port)
621
+ th = Thread.new do
622
+ while true
623
+ begin
624
+ in_data, _addr = sock.recvfrom_nonblock(16)
625
+ if in_data
626
+ responses << in_data
627
+ break
628
+ end
629
+ rescue IO::WaitReadable
630
+ IO.select([sock])
631
+ end
632
+ end
633
+ true
634
+ end
635
+ sock.write "yay\nfoo\n"
636
+ th.join(5)
637
+ ensure
638
+ sock.close
639
+ end
640
+ end
641
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
642
+ assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
643
+ assert_equal ["ack\n","ack\n","ack\n"], responses
644
+ end
645
+
646
+ test 'creates a udp server to read and write data using IPv6' do
647
+ omit "IPv6 unavailable here" unless ipv6_enabled?
648
+
649
+ received = ""
650
+ responses = []
651
+ @d.server_create_udp(:s, @port, bind: "::1", max_bytes: 128) do |data, sock|
652
+ received << data
653
+ sock.write "ack\n"
654
+ end
655
+ bind_port = unused_port
656
+ 3.times do
657
+ begin
658
+ sock = UDPSocket.new(Socket::AF_INET6)
659
+ sock.bind("::1", bind_port)
660
+ th = Thread.new do
661
+ responses << sock.recv(16)
662
+ true
663
+ end
664
+ sock.connect("::1", @port)
665
+ sock.write "yay\nfoo\n"
666
+ th.join(5)
667
+ ensure
668
+ sock.close
669
+ end
670
+ end
671
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
672
+ assert_equal "yay\nfoo\nyay\nfoo\nyay\nfoo\n", received
673
+ assert_equal ["ack\n","ack\n","ack\n"], responses
674
+ end
675
+
676
+ test 'does not resolve name of client address in default' do
677
+ received = ""
678
+ sources = []
679
+ @d.server_create_udp(:s, @port, max_bytes: 128) do |data, sock|
680
+ received << data
681
+ sources << sock.remote_host
682
+ end
683
+ 3.times do
684
+ sock = UDPSocket.new(Socket::AF_INET)
685
+ sock.connect("127.0.0.1", @port)
686
+ sock.puts "yay"
687
+ sock.close
688
+ end
689
+ waiting(10){ sleep 0.1 until received.bytesize == 12 }
690
+ assert_equal "yay\nyay\nyay\n", received
691
+ assert{ sources.all?{|s| s == "127.0.0.1" } }
692
+ end
693
+
694
+ test 'does resolve name of client address if resolve_name is true' do
695
+ hostname = Socket.getnameinfo([nil, nil, nil, "127.0.0.1"])[0]
696
+
697
+ received = ""
698
+ sources = []
699
+ @d.server_create_udp(:s, @port, resolve_name: true, max_bytes: 128) do |data, sock|
700
+ received << data
701
+ sources << sock.remote_host
702
+ end
703
+ 3.times do
704
+ sock = UDPSocket.new(Socket::AF_INET)
705
+ sock.connect("127.0.0.1", @port)
706
+ sock.puts "yay"
707
+ sock.close
708
+ end
709
+ waiting(10){ sleep 0.1 until received.bytesize == 12 }
710
+ assert_equal "yay\nyay\nyay\n", received
711
+ assert{ sources.all?{|s| s == hostname } }
712
+ end
713
+
714
+ test 'raises error if plugin registers data callback for connection object from #server_create' do
715
+ received = ""
716
+ errors = []
717
+ @d.server_create_udp(:s, @port, max_bytes: 128) do |data, sock|
718
+ received << data
719
+ begin
720
+ sock.data{|d| received << d.upcase }
721
+ rescue => e
722
+ errors << e
723
+ end
724
+ end
725
+ sock = UDPSocket.new(Socket::AF_INET)
726
+ sock.connect("127.0.0.1", @port)
727
+ sock.write "foo\n"
728
+ sock.close
729
+
730
+ waiting(10){ sleep 0.1 until received.bytesize == 4 && errors.size == 1 }
731
+ assert_equal "foo\n", received
732
+ assert_equal 1, errors.size
733
+ assert_equal "BUG: this event is disabled for udp: data", errors.first.message
734
+ end
735
+
736
+ test 'raise error if plugin registers write_complete callback for udp' do
737
+ received = ""
738
+ errors = []
739
+ @d.server_create_udp(:s, @port, max_bytes: 128) do |data, sock|
740
+ received << data
741
+ begin
742
+ sock.on(:write_complete){|conn| "" }
743
+ rescue => e
744
+ errors << e
745
+ end
746
+ end
747
+ sock = UDPSocket.new(Socket::AF_INET)
748
+ sock.connect("127.0.0.1", @port)
749
+ sock.write "foo\n"
750
+ sock.close
751
+
752
+ waiting(10){ sleep 0.1 until received.bytesize == 4 && errors.size == 1 }
753
+ assert_equal "foo\n", received
754
+ assert_equal 1, errors.size
755
+ assert_equal "BUG: this event is disabled for udp: write_complete", errors.first.message
756
+ end
757
+
758
+ test 'raises error if plugin registers close callback for udp' do
759
+ received = ""
760
+ errors = []
761
+ @d.server_create_udp(:s, @port, max_bytes: 128) do |data, sock|
762
+ received << data
763
+ begin
764
+ sock.on(:close){|d| "" }
765
+ rescue => e
766
+ errors << e
767
+ end
768
+ end
769
+ sock = UDPSocket.new(Socket::AF_INET)
770
+ sock.connect("127.0.0.1", @port)
771
+ sock.write "foo\n"
772
+ sock.close
773
+
774
+ waiting(10){ sleep 0.1 until received.bytesize == 4 && errors.size == 1 }
775
+ assert_equal "foo\n", received
776
+ assert_equal 1, errors.size
777
+ assert_equal "BUG: this event is disabled for udp: close", errors.first.message
778
+ end
779
+
780
+ test 'can bind IPv4 / IPv6 together' do
781
+ omit "IPv6 unavailable here" unless ipv6_enabled?
782
+
783
+ assert_nothing_raised do
784
+ @d.server_create_udp(:s_ipv4_udp, @port, bind: '0.0.0.0', shared: false, max_bytes: 128) do |data, sock|
785
+ # ...
786
+ end
787
+ @d.server_create_udp(:s_ipv6_udp, @port, bind: '::', shared: false, max_bytes: 128) do |data, sock|
788
+ # ...
789
+ end
790
+ end
791
+ end
792
+ end
793
+
794
+ module CertUtil
795
+ extend Fluent::PluginHelper::CertOption
796
+ end
797
+
798
+ def create_ca_options
799
+ {
800
+ private_key_length: 2048,
801
+ country: 'US',
802
+ state: 'CA',
803
+ locality: 'Mountain View',
804
+ common_name: 'ca.testing.fluentd.org',
805
+ expiration: 30 * 86400,
806
+ digest: :sha256,
807
+ }
808
+ end
809
+
810
+ def create_server_options
811
+ {
812
+ private_key_length: 2048,
813
+ country: 'US',
814
+ state: 'CA',
815
+ locality: 'Mountain View',
816
+ common_name: 'server.testing.fluentd.org',
817
+ expiration: 30 * 86400,
818
+ digest: :sha256,
819
+ }
820
+ end
821
+
822
+ def write_cert_and_key(cert_path, cert, key_path, key, passphrase)
823
+ File.open(cert_path, "w"){|f| f.write(cert.to_pem) }
824
+ # Write the secret key (raw or encrypted by AES256) in PEM format
825
+ key_str = passphrase ? key.export(OpenSSL::Cipher.new("AES-256-CBC"), passphrase) : key.export
826
+ File.open(key_path, "w"){|f| f.write(key_str) }
827
+ File.chmod(0600, cert_path, key_path)
828
+ end
829
+
830
+ def create_server_pair_signed_by_self(cert_path, private_key_path, passphrase)
831
+ cert, key, _ = CertUtil.cert_option_generate_server_pair_self_signed(create_server_options)
832
+ write_cert_and_key(cert_path, cert, private_key_path, key, passphrase)
833
+ return cert
834
+ end
835
+
836
+ def create_ca_pair_signed_by_self(cert_path, private_key_path, passphrase)
837
+ cert, key, _ = CertUtil.cert_option_generate_ca_pair_self_signed(create_ca_options)
838
+ write_cert_and_key(cert_path, cert, private_key_path, key, passphrase)
839
+ end
840
+
841
+ def create_server_pair_signed_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, passphrase)
842
+ cert, key, _ = CertUtil.cert_option_generate_server_pair_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, create_server_options)
843
+ write_cert_and_key(cert_path, cert, private_key_path, key, passphrase)
844
+ return cert
845
+ end
846
+
847
+ def create_server_pair_chained_with_root_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, passphrase)
848
+ root_cert, root_key, _ = CertUtil.cert_option_generate_ca_pair_self_signed(create_ca_options)
849
+ write_cert_and_key(ca_cert_path, root_cert, ca_key_path, root_key, ca_key_passphrase)
850
+
851
+ intermediate_ca_options = create_ca_options
852
+ intermediate_ca_options[:common_name] = 'ca2.testing.fluentd.org'
853
+ chain_cert, chain_key = CertUtil.cert_option_generate_pair(intermediate_ca_options, root_cert.subject)
854
+ chain_cert.add_extension OpenSSL::X509::Extension.new('basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(true)]))
855
+ chain_cert.sign(root_key, "sha256")
856
+
857
+ server_cert, server_key, _ = CertUtil.cert_option_generate_pair(create_server_options, chain_cert.subject)
858
+ factory = OpenSSL::X509::ExtensionFactory.new
859
+ server_cert.add_extension(factory.create_extension('basicConstraints', 'CA:FALSE'))
860
+ server_cert.add_extension(factory.create_extension('nsCertType', 'server'))
861
+ server_cert.sign(chain_key, "sha256")
862
+
863
+ # write chained cert
864
+ File.open(cert_path, "w") do |f|
865
+ f.write server_cert.to_pem
866
+ f.write chain_cert.to_pem
867
+ end
868
+ key_str = passphrase ? server_key.export(OpenSSL::Cipher.new("AES-256-CBC"), passphrase) : server_key.export
869
+ File.open(private_key_path, "w"){|f| f.write(key_str) }
870
+ File.chmod(0600, cert_path, private_key_path)
871
+ end
872
+
873
+ def open_tls_session(addr, port, version: Fluent::TLS::DEFAULT_VERSION, verify: true, cert_path: nil, selfsigned: true, hostname: nil)
874
+ context = OpenSSL::SSL::SSLContext.new
875
+ context.set_params({})
876
+ if verify
877
+ cert_store = OpenSSL::X509::Store.new
878
+ cert_store.set_default_paths
879
+ if selfsigned && OpenSSL::X509.const_defined?('V_FLAG_CHECK_SS_SIGNATURE')
880
+ cert_store.flags = OpenSSL::X509::V_FLAG_CHECK_SS_SIGNATURE
881
+ end
882
+ if cert_path
883
+ cert_store.add_file(cert_path)
884
+ end
885
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
886
+ context.cert_store = cert_store
887
+ if !hostname
888
+ context.verify_hostname = false # In test code, using hostname to be connected is very difficult
889
+ end
890
+ else
891
+ context.verify_mode = OpenSSL::SSL::VERIFY_NONE
892
+ end
893
+ Fluent::TLS.set_version_to_context(context, version, nil, nil)
894
+
895
+ sock = OpenSSL::SSL::SSLSocket.new(TCPSocket.new(addr, port), context)
896
+ sock.hostname = hostname if hostname && sock.respond_to?(:hostname)
897
+ sock.connect
898
+ yield sock
899
+ ensure
900
+ sock.close rescue nil
901
+ end
902
+
903
+ def assert_certificate(cert, expected_extensions)
904
+ get_extension = lambda do |oid|
905
+ cert.extensions.detect { |e| e.oid == oid }
906
+ end
907
+
908
+ assert_true cert.serial > 1
909
+ assert_equal 2, cert.version
910
+
911
+ expected_extensions.each do |ext|
912
+ expected_oid, expected_value = ext
913
+ assert_equal expected_value, get_extension.call(expected_oid).value
914
+ end
915
+ end
916
+
917
+ sub_test_case '#server_create_tls with various certificate options' do
918
+ setup do
919
+ @d = Dummy.new # to get plugin not configured/started yet
920
+
921
+ @certs_dir = File.join(TMP_DIR, "tls_certs")
922
+ @server_cert_dir = File.join(@certs_dir, "server")
923
+ FileUtils.rm_rf @certs_dir
924
+ FileUtils.mkdir_p @server_cert_dir
925
+ end
926
+
927
+ sub_test_case 'using tls_options arguments to specify cert options' do
928
+ setup do
929
+ @d.configure(config_element()); @d.start; @d.after_start
930
+ end
931
+
932
+ test 'create dynamic self-signed cert/key pair (without any verification from clients)' do
933
+ # insecure
934
+ tls_options = {
935
+ protocol: :tls,
936
+ version: :'TLSv1_2',
937
+ ciphers: 'ALL:!aNULL:!eNULL:!SSLv2',
938
+ insecure: true,
939
+ generate_private_key_length: 2048,
940
+ generate_cert_country: 'US',
941
+ generate_cert_state: 'CA',
942
+ generate_cert_locality: 'Mountain View',
943
+ generate_cert_common_name: 'myserver.testing.fluentd.org',
944
+ generate_cert_expiration: 10 * 365 * 86400,
945
+ generate_cert_digest: :sha256,
946
+ }
947
+
948
+ received = ""
949
+ @d.server_create_tls(:s, @port, tls_options: tls_options) do |data, conn|
950
+ received << data
951
+ end
952
+ assert_raise "" do
953
+ open_tls_session('127.0.0.1', @port) do |sock|
954
+ sock.post_connection_check('myserver.testing.fluentd.org')
955
+ # cannot connect ....
956
+ end
957
+ end
958
+ open_tls_session('127.0.0.1', @port, verify: false) do |sock|
959
+ sock.puts "yay"
960
+ sock.puts "foo"
961
+ end
962
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
963
+ assert_equal "yay\nfoo\n", received
964
+ end
965
+
966
+ data('with passphrase' => 'yaaaaaaaaaaaaaaaaaaay',
967
+ 'without passphrase' => nil)
968
+ test 'load self-signed cert/key pair (files), verified from clients using cert files' do |private_key_passphrase|
969
+ cert_path = File.join(@server_cert_dir, "cert.pem")
970
+ private_key_path = File.join(@certs_dir, "server.key.pem")
971
+ cert = create_server_pair_signed_by_self(cert_path, private_key_path, private_key_passphrase)
972
+
973
+ assert_certificate(cert,[
974
+ ['basicConstraints', 'CA:FALSE'],
975
+ ['nsCertType', 'SSL Server']
976
+ ])
977
+
978
+ tls_options = {
979
+ protocol: :tls,
980
+ version: :'TLSv1_2',
981
+ ciphers: 'ALL:!aNULL:!eNULL:!SSLv2',
982
+ insecure: false,
983
+ cert_path: cert_path,
984
+ private_key_path: private_key_path,
985
+ }
986
+ tls_options[:private_key_passphrase] = private_key_passphrase if private_key_passphrase
987
+ received = ""
988
+ @d.server_create_tls(:s, @port, tls_options: tls_options) do |data, conn|
989
+ received << data
990
+ end
991
+ assert_raise "" do
992
+ open_tls_session('127.0.0.1', @port) do |sock|
993
+ sock.post_connection_check('server.testing.fluentd.org')
994
+ # cannot connect by failing verification without server cert
995
+ end
996
+ end
997
+ open_tls_session('127.0.0.1', @port, cert_path: cert_path) do |sock|
998
+ sock.puts "yay"
999
+ sock.puts "foo"
1000
+ end
1001
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1002
+ assert_equal "yay\nfoo\n", received
1003
+ end
1004
+
1005
+ data('with passphrase' => "fooooooooooooooooooooooooo",
1006
+ 'without passphrase' => nil)
1007
+ test 'create dynamic server cert by private CA cert file, verified from clients using CA cert file' do |ca_key_passphrase|
1008
+ ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
1009
+ ca_key_path = File.join(@certs_dir, "ca.key.pem")
1010
+ create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, ca_key_passphrase)
1011
+
1012
+ tls_options = {
1013
+ protocol: :tls,
1014
+ version: :'TLSv1_2',
1015
+ ciphers: 'ALL:!aNULL:!eNULL:!SSLv2',
1016
+ insecure: false,
1017
+ ca_cert_path: ca_cert_path,
1018
+ ca_private_key_path: ca_key_path,
1019
+ generate_private_key_length: 2048,
1020
+ }
1021
+ tls_options[:ca_private_key_passphrase] = ca_key_passphrase if ca_key_passphrase
1022
+ received = ""
1023
+ @d.server_create_tls(:s, @port, tls_options: tls_options) do |data, conn|
1024
+ received << data
1025
+ end
1026
+ open_tls_session('127.0.0.1', @port, cert_path: ca_cert_path) do |sock|
1027
+ sock.puts "yay"
1028
+ sock.puts "foo"
1029
+ end
1030
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1031
+ assert_equal "yay\nfoo\n", received
1032
+ end
1033
+
1034
+ data('with passphrase' => ["foooooooo", "yaaaaaaaaaaaaaaaaaaay"],
1035
+ 'without passphrase' => [nil, nil])
1036
+ test 'load static server cert by private CA cert file, verified from clients using CA cert file' do |(ca_key_passphrase, private_key_passphrase)|
1037
+ ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
1038
+ ca_key_path = File.join(@certs_dir, "ca.key.pem")
1039
+ create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, ca_key_passphrase)
1040
+
1041
+ cert_path = File.join(@server_cert_dir, "cert.pem")
1042
+ private_key_path = File.join(@certs_dir, "server.key.pem")
1043
+ cert = create_server_pair_signed_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, private_key_passphrase)
1044
+
1045
+ assert_certificate(cert,[
1046
+ ['basicConstraints', 'CA:FALSE'],
1047
+ ['nsCertType', 'SSL Server'],
1048
+ ['keyUsage', 'Digital Signature, Key Encipherment'],
1049
+ ['extendedKeyUsage', 'TLS Web Server Authentication']
1050
+ ])
1051
+
1052
+ tls_options = {
1053
+ protocol: :tls,
1054
+ version: :'TLSv1_2',
1055
+ ciphers: 'ALL:!aNULL:!eNULL:!SSLv2',
1056
+ insecure: false,
1057
+ cert_path: cert_path,
1058
+ private_key_path: private_key_path,
1059
+ }
1060
+ tls_options[:private_key_passphrase] = private_key_passphrase if private_key_passphrase
1061
+ received = ""
1062
+ @d.server_create_tls(:s, @port, tls_options: tls_options) do |data, conn|
1063
+ received << data
1064
+ end
1065
+ open_tls_session('127.0.0.1', @port, cert_path: ca_cert_path) do |sock|
1066
+ sock.puts "yay"
1067
+ sock.puts "foo"
1068
+ end
1069
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1070
+ assert_equal "yay\nfoo\n", received
1071
+ end
1072
+
1073
+ data('with passphrase' => ["foooooooo", "yaaaaaaaaaaaaaaaaaaay"],
1074
+ 'without passphrase' => [nil, nil])
1075
+ test 'load chained server cert by private CA cert file, verified from clients using CA cert file as root' do |(ca_key_passphrase, private_key_passphrase)|
1076
+ ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
1077
+ ca_key_path = File.join(@certs_dir, "ca.key.pem")
1078
+ cert_path = File.join(@server_cert_dir, "cert.pem")
1079
+ private_key_path = File.join(@certs_dir, "server.key.pem")
1080
+ create_server_pair_chained_with_root_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, private_key_passphrase)
1081
+
1082
+ tls_options = {
1083
+ protocol: :tls,
1084
+ version: :'TLSv1_2',
1085
+ ciphers: 'ALL:!aNULL:!eNULL:!SSLv2',
1086
+ insecure: false,
1087
+ cert_path: cert_path,
1088
+ private_key_path: private_key_path,
1089
+ }
1090
+ tls_options[:private_key_passphrase] = private_key_passphrase if private_key_passphrase
1091
+ received = ""
1092
+ @d.server_create_tls(:s, @port, tls_options: tls_options) do |data, conn|
1093
+ received << data
1094
+ end
1095
+ open_tls_session('127.0.0.1', @port, cert_path: ca_cert_path) do |sock|
1096
+ sock.puts "yay"
1097
+ sock.puts "foo"
1098
+ end
1099
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1100
+ assert_equal "yay\nfoo\n", received
1101
+ end
1102
+ end
1103
+
1104
+ sub_test_case 'using configurations to specify cert options' do
1105
+ test 'create dynamic self-signed cert/key pair (without any verification from clients)' do
1106
+ # insecure
1107
+ transport_opts = {
1108
+ 'insecure' => 'true',
1109
+ }
1110
+ transport_conf = config_element('transport', 'tls', transport_opts)
1111
+ conf = config_element('match', 'tag.*', {}, [transport_conf])
1112
+
1113
+ @d.configure(conf); @d.start; @d.after_start
1114
+
1115
+ received = ""
1116
+ @d.server_create_tls(:s, @port) do |data, conn|
1117
+ received << data
1118
+ end
1119
+ assert_raise "" do
1120
+ open_tls_session('127.0.0.1', @port) do |sock|
1121
+ sock.post_connection_check('myserver.testing.fluentd.org')
1122
+ # cannot connect ....
1123
+ end
1124
+ end
1125
+ open_tls_session('127.0.0.1', @port, verify: false) do |sock|
1126
+ sock.puts "yay"
1127
+ sock.puts "foo"
1128
+ end
1129
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1130
+ assert_equal "yay\nfoo\n", received
1131
+ end
1132
+
1133
+ data('with passphrase' => "yaaaaaaaaaaaaaaaaaaay",
1134
+ 'without passphrase' => nil)
1135
+ test 'load self-signed cert/key pair (files), verified from clients using cert files' do |private_key_passphrase|
1136
+ cert_path = File.join(@server_cert_dir, "cert.pem")
1137
+ private_key_path = File.join(@certs_dir, "server.key.pem")
1138
+ create_server_pair_signed_by_self(cert_path, private_key_path, private_key_passphrase)
1139
+
1140
+ transport_opts = {
1141
+ 'cert_path' => cert_path,
1142
+ 'private_key_path' => private_key_path,
1143
+ }
1144
+ transport_opts['private_key_passphrase'] = private_key_passphrase if private_key_passphrase
1145
+ transport_conf = config_element('transport', 'tls', transport_opts)
1146
+ conf = config_element('match', 'tag.*', {}, [transport_conf])
1147
+
1148
+ @d.configure(conf); @d.start; @d.after_start
1149
+
1150
+ received = ""
1151
+ @d.server_create_tls(:s, @port) do |data, conn|
1152
+ received << data
1153
+ end
1154
+ assert_raise "" do
1155
+ open_tls_session('127.0.0.1', @port) do |sock|
1156
+ sock.post_connection_check('server.testing.fluentd.org')
1157
+ # cannot connect by failing verification without server cert
1158
+ end
1159
+ end
1160
+ open_tls_session('127.0.0.1', @port, cert_path: cert_path) do |sock|
1161
+ sock.puts "yay"
1162
+ sock.puts "foo"
1163
+ end
1164
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1165
+ assert_equal "yay\nfoo\n", received
1166
+ end
1167
+
1168
+ data('with passphrase' => "fooooooooooooooooooooooooo",
1169
+ 'without passphrase' => nil)
1170
+ test 'create dynamic server cert by private CA cert file, verified from clients using CA cert file' do |ca_key_passphrase|
1171
+ ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
1172
+ ca_key_path = File.join(@certs_dir, "ca.key.pem")
1173
+ create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, ca_key_passphrase)
1174
+
1175
+ transport_opts = {
1176
+ 'ca_cert_path' => ca_cert_path,
1177
+ 'ca_private_key_path' => ca_key_path,
1178
+ }
1179
+ transport_opts['ca_private_key_passphrase'] = ca_key_passphrase if ca_key_passphrase
1180
+ transport_conf = config_element('transport', 'tls', transport_opts)
1181
+ conf = config_element('match', 'tag.*', {}, [transport_conf])
1182
+
1183
+ @d.configure(conf); @d.start; @d.after_start
1184
+
1185
+ received = ""
1186
+ @d.server_create_tls(:s, @port) do |data, conn|
1187
+ received << data
1188
+ end
1189
+ open_tls_session('127.0.0.1', @port, cert_path: ca_cert_path) do |sock|
1190
+ sock.puts "yay"
1191
+ sock.puts "foo"
1192
+ end
1193
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1194
+ assert_equal "yay\nfoo\n", received
1195
+ end
1196
+
1197
+ data('with passphrase' => ["foooooooo", "yaaaaaaaaaaaaaaaaaaay"],
1198
+ 'without passphrase' => [nil, nil])
1199
+ test 'load static server cert by private CA cert file, verified from clients using CA cert file' do |(ca_key_passphrase, private_key_passphrase)|
1200
+ ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
1201
+ ca_key_path = File.join(@certs_dir, "ca.key.pem")
1202
+ create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, ca_key_passphrase)
1203
+
1204
+ cert_path = File.join(@server_cert_dir, "cert.pem")
1205
+ private_key_path = File.join(@certs_dir, "server.key.pem")
1206
+ create_server_pair_signed_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, private_key_passphrase)
1207
+
1208
+ transport_opts = {
1209
+ 'cert_path' => cert_path,
1210
+ 'private_key_path' => private_key_path,
1211
+ }
1212
+ transport_opts['private_key_passphrase'] = private_key_passphrase if private_key_passphrase
1213
+ transport_conf = config_element('transport', 'tls', transport_opts)
1214
+ conf = config_element('match', 'tag.*', {}, [transport_conf])
1215
+
1216
+ @d.configure(conf); @d.start; @d.after_start
1217
+
1218
+ received = ""
1219
+ @d.server_create_tls(:s, @port) do |data, conn|
1220
+ received << data
1221
+ end
1222
+ open_tls_session('127.0.0.1', @port, cert_path: ca_cert_path) do |sock|
1223
+ sock.puts "yay"
1224
+ sock.puts "foo"
1225
+ end
1226
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1227
+ assert_equal "yay\nfoo\n", received
1228
+ end
1229
+
1230
+ data('with passphrase' => ["foooooooo", "yaaaaaaaaaaaaaaaaaaay"],
1231
+ 'without passphrase' => [nil, nil])
1232
+ test 'load chained server cert by private CA cert file, verified from clients using CA cert file as root' do |(ca_key_passphrase, private_key_passphrase)|
1233
+ ca_cert_path = File.join(@certs_dir, "ca_cert.pem")
1234
+ ca_key_path = File.join(@certs_dir, "ca.key.pem")
1235
+ cert_path = File.join(@server_cert_dir, "cert.pem")
1236
+ private_key_path = File.join(@certs_dir, "server.key.pem")
1237
+ create_server_pair_chained_with_root_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, private_key_passphrase)
1238
+
1239
+ transport_opts = {
1240
+ 'cert_path' => cert_path,
1241
+ 'private_key_path' => private_key_path,
1242
+ }
1243
+ transport_opts['private_key_passphrase'] = private_key_passphrase if private_key_passphrase
1244
+ transport_conf = config_element('transport', 'tls', transport_opts)
1245
+ conf = config_element('match', 'tag.*', {}, [transport_conf])
1246
+
1247
+ @d.configure(conf); @d.start; @d.after_start
1248
+
1249
+ received = ""
1250
+ @d.server_create_tls(:s, @port) do |data, conn|
1251
+ received << data
1252
+ end
1253
+ open_tls_session('127.0.0.1', @port, cert_path: ca_cert_path) do |sock|
1254
+ sock.puts "yay"
1255
+ sock.puts "foo"
1256
+ end
1257
+ waiting(10){ sleep 0.1 until received.bytesize == 8 }
1258
+ assert_equal "yay\nfoo\n", received
1259
+ end
1260
+
1261
+ test 'set ciphers' do
1262
+ cert_path = File.join(@server_cert_dir, "cert.pem")
1263
+ private_key_path = File.join(@certs_dir, "server.key.pem")
1264
+ create_server_pair_signed_by_self(cert_path, private_key_path, nil)
1265
+ tls_options = {
1266
+ protocol: :tls,
1267
+ version: :TLSv1_2,
1268
+ ciphers: 'SHA256',
1269
+ insecure: false,
1270
+ cert_path: cert_path,
1271
+ private_key_path: private_key_path,
1272
+ }
1273
+ conf = @d.server_create_transport_section_object(tls_options)
1274
+ ctx = @d.cert_option_create_context(conf.version, conf.insecure, conf.ciphers, conf)
1275
+ matched = false
1276
+ ctx.ciphers.each do |cipher|
1277
+ cipher_name, tls_version = cipher
1278
+ # OpenSSL 1.0.2: "TLSv1/SSLv3"
1279
+ # OpenSSL 1.1.1: "TLSv1.2"
1280
+ if tls_version == "TLSv1/SSLv3" || tls_version == "TLSv1.2"
1281
+ matched = true
1282
+ unless cipher_name.match(/#{conf.ciphers}/)
1283
+ matched = false
1284
+ break
1285
+ end
1286
+ end
1287
+ end
1288
+
1289
+ error_msg = build_message("Unexpected ciphers for #{conf.version}",
1290
+ "<?>\nwas expected to include only <?> ciphers for #{conf.version}",
1291
+ ctx.ciphers, conf.ciphers)
1292
+ assert(matched, error_msg)
1293
+ end
1294
+ end
1295
+ end
1296
+
1297
+ sub_test_case '#server_create_tls' do
1298
+ setup do
1299
+ @certs_dir = File.join(TMP_DIR, "tls_certs")
1300
+ FileUtils.rm_rf @certs_dir
1301
+ FileUtils.mkdir_p @certs_dir
1302
+
1303
+ @server_cert_dir = File.join(@certs_dir, "server")
1304
+ FileUtils.mkdir_p @server_cert_dir
1305
+
1306
+ @cert_path = File.join(@server_cert_dir, "cert.pem")
1307
+ private_key_path = File.join(@certs_dir, "server.key.pem")
1308
+ private_key_passphrase = "yaaaaaaaaaaaaaaaaaaay"
1309
+ create_server_pair_signed_by_self(@cert_path, private_key_path, private_key_passphrase)
1310
+
1311
+ @default_hostname = ::Socket.gethostname
1312
+
1313
+ @tls_options = {
1314
+ protocol: :tls,
1315
+ version: :'TLSv1_2',
1316
+ ciphers: 'ALL:!aNULL:!eNULL:!SSLv2',
1317
+ insecure: false,
1318
+ cert_path: @cert_path,
1319
+ private_key_path: private_key_path,
1320
+ private_key_passphrase: private_key_passphrase,
1321
+ }
1322
+ end
1323
+
1324
+ test 'can accept all keyword arguments valid for tcp/tls server' do
1325
+ assert_nothing_raised do
1326
+ @d.server_create_tls(:s, @port, bind: '127.0.0.1', shared: false, resolve_name: true, linger_timeout: 10, backlog: 500, tls_options: @tls_options, send_keepalive_packet: true) do |data, conn|
1327
+ # ...
1328
+ end
1329
+ end
1330
+ end
1331
+
1332
+ test 'creates a tls server just to read data' do
1333
+ received = ""
1334
+ @d.server_create_tls(:s, @port, tls_options: @tls_options) do |data, conn|
1335
+ received << data
1336
+ end
1337
+ 3.times do
1338
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path) do |sock|
1339
+ sock.puts "yay"
1340
+ sock.puts "foo"
1341
+ end
1342
+ end
1343
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
1344
+ assert_equal 3, received.scan("yay\n").size
1345
+ assert_equal 3, received.scan("foo\n").size
1346
+ end
1347
+
1348
+ test 'creates a tls server to read and write data' do
1349
+ received = ""
1350
+ responses = []
1351
+ @d.server_create_tls(:s, @port, tls_options: @tls_options) do |data, conn|
1352
+ received << data
1353
+ conn.write "ack\n"
1354
+ end
1355
+ 3.times do
1356
+ # open_tls_session('127.0.0.1', @port, cert_path: @cert_path, hostname: @default_hostname) do |sock|
1357
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path) do |sock|
1358
+ sock.puts "yay"
1359
+ sock.puts "foo"
1360
+ responses << sock.readline
1361
+ end
1362
+ end
1363
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
1364
+ assert_equal 3, received.scan("yay\n").size
1365
+ assert_equal 3, received.scan("foo\n").size
1366
+ assert_equal ["ack\n","ack\n","ack\n"], responses
1367
+ end
1368
+
1369
+ test 'creates a tls server to read and write data using IPv6' do
1370
+ omit "IPv6 unavailable here" unless ipv6_enabled?
1371
+
1372
+ received = ""
1373
+ responses = []
1374
+ @d.server_create_tls(:s, @port, bind: "::1", tls_options: @tls_options) do |data, conn|
1375
+ received << data
1376
+ conn.write "ack\n"
1377
+ end
1378
+ 3.times do
1379
+ # open_tls_session('::1', @port, cert_path: @cert_path, hostname: @default_hostname) do |sock|
1380
+ open_tls_session('::1', @port, cert_path: @cert_path) do |sock|
1381
+ sock.puts "yay"
1382
+ sock.puts "foo"
1383
+ responses << sock.readline
1384
+ end
1385
+ end
1386
+ waiting(10){ sleep 0.1 until received.bytesize == 24 }
1387
+ assert_equal 3, received.scan("yay\n").size
1388
+ assert_equal 3, received.scan("foo\n").size
1389
+ assert_equal ["ack\n","ack\n","ack\n"], responses
1390
+ end
1391
+
1392
+ test 'does not resolve name of client address in default' do
1393
+ received = ""
1394
+ sources = []
1395
+ @d.server_create_tls(:s, @port, tls_options: @tls_options) do |data, conn|
1396
+ received << data
1397
+ sources << conn.remote_host
1398
+ end
1399
+ 3.times do
1400
+ # open_tls_session('127.0.0.1', @port, cert_path: @cert_path, hostname: @default_hostname) do |sock|
1401
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path) do |sock|
1402
+ sock.puts "yay"
1403
+ end
1404
+ end
1405
+ waiting(10){ sleep 0.1 until received.bytesize == 12 }
1406
+ assert_equal 3, received.scan("yay\n").size
1407
+ assert{ sources.all?{|s| s == "127.0.0.1" } }
1408
+ end
1409
+
1410
+ test 'does resolve name of client address if resolve_name is true' do
1411
+ hostname = Socket.getnameinfo([nil, nil, nil, "127.0.0.1"])[0]
1412
+
1413
+ received = ""
1414
+ sources = []
1415
+ @d.server_create_tls(:s, @port, resolve_name: true, tls_options: @tls_options) do |data, conn|
1416
+ received << data
1417
+ sources << conn.remote_host
1418
+ end
1419
+ 3.times do
1420
+ # open_tls_session('127.0.0.1', @port, cert_path: @cert_path, hostname: @default_hostname) do |sock|
1421
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path) do |sock|
1422
+ sock.puts "yay"
1423
+ end
1424
+ end
1425
+ waiting(10){ sleep 0.1 until received.bytesize == 12 }
1426
+ assert_equal 3, received.scan("yay\n").size
1427
+ assert{ sources.all?{|s| s == hostname } }
1428
+ end
1429
+
1430
+ test 'can keep connections alive for tls if keepalive specified' do
1431
+ # pend "not implemented yet"
1432
+ end
1433
+
1434
+ test 'raises error if plugin registers data callback for connection object from #server_create' do
1435
+ received = ""
1436
+ errors = []
1437
+ @d.server_create_tls(:s, @port, tls_options: @tls_options) do |data, conn|
1438
+ received << data
1439
+ begin
1440
+ conn.data{|d| received << d.upcase }
1441
+ rescue => e
1442
+ errors << e
1443
+ end
1444
+ end
1445
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path) do |sock|
1446
+ sock.puts "foo"
1447
+ end
1448
+ waiting(10){ sleep 0.1 until received.bytesize == 4 || errors.size == 1 }
1449
+ assert_equal "foo\n", received
1450
+ assert_equal 1, errors.size
1451
+ assert_equal "data callback can be registered just once, but registered twice", errors.first.message
1452
+ end
1453
+
1454
+ test 'can call write_complete callback if registered' do
1455
+ buffer = ""
1456
+ lines = []
1457
+ responses = []
1458
+ response_completes = []
1459
+ @d.server_create_tls(:s, @port, tls_options: @tls_options) do |data, conn|
1460
+ conn.on(:write_complete){|c| response_completes << true }
1461
+ buffer << data
1462
+ if idx = buffer.index("\n")
1463
+ lines << buffer.slice!(0,idx+1)
1464
+ conn.write "ack\n"
1465
+ end
1466
+ end
1467
+ 3.times do
1468
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path) do |sock|
1469
+ sock.write "yay"
1470
+ sock.write "foo\n"
1471
+ begin
1472
+ responses << sock.readline
1473
+ rescue EOFError, IOError, Errno::ECONNRESET
1474
+ # ignore
1475
+ end
1476
+ sock.close
1477
+ end
1478
+ end
1479
+ waiting(10){ sleep 0.1 until lines.size == 3 && response_completes.size == 3 }
1480
+ assert_equal ["yayfoo\n", "yayfoo\n", "yayfoo\n"], lines
1481
+ assert_equal ["ack\n","ack\n","ack\n"], responses
1482
+ assert_equal [true, true, true], response_completes
1483
+ end
1484
+
1485
+ test 'can call close callback if registered' do
1486
+ buffer = ""
1487
+ lines = []
1488
+ callback_results = []
1489
+ @d.server_create_tls(:s, @port, tls_options: @tls_options) do |data, conn|
1490
+ conn.on(:close){|c| callback_results << "closed" }
1491
+ buffer << data
1492
+ if idx = buffer.index("\n")
1493
+ lines << buffer.slice!(0,idx+1)
1494
+ conn.write "ack\n"
1495
+ end
1496
+ end
1497
+ 3.times do
1498
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path) do |sock|
1499
+ sock.write "yay"
1500
+ sock.write "foo\n"
1501
+ begin
1502
+ while line = sock.readline
1503
+ if line == "ack\n"
1504
+ sock.close
1505
+ end
1506
+ end
1507
+ rescue EOFError, IOError, Errno::ECONNRESET
1508
+ # ignore
1509
+ end
1510
+ end
1511
+ end
1512
+ waiting(10){ sleep 0.1 until lines.size == 3 && callback_results.size == 3 }
1513
+ assert_equal ["yayfoo\n", "yayfoo\n", "yayfoo\n"], lines
1514
+ assert_equal ["closed", "closed", "closed"], callback_results
1515
+ end
1516
+
1517
+ sub_test_case 'TLS version connection check' do
1518
+ test "can't connect with different TLS version" do
1519
+ @d.server_create_tls(:s, @port, tls_options: @tls_options) do |data, conn|
1520
+ end
1521
+ if defined?(OpenSSL::SSL::TLS1_3_VERSION)
1522
+ version = :'TLS1_3'
1523
+ else
1524
+ version = :'TLS1_1'
1525
+ end
1526
+ assert_raise(OpenSSL::SSL::SSLError, Errno::ECONNRESET) {
1527
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path, version: version) do |sock|
1528
+ end
1529
+ }
1530
+ end
1531
+
1532
+ test "can specify multiple TLS versions by min_version/max_version" do
1533
+ omit "min_version=/max_version= is not supported" unless Fluent::TLS::MIN_MAX_AVAILABLE
1534
+
1535
+ min_version = :'TLS1_2'
1536
+ if defined?(OpenSSL::SSL::TLS1_3_VERSION)
1537
+ max_version = :'TLS1_3'
1538
+ else
1539
+ max_version = :'TLS1_2'
1540
+ end
1541
+
1542
+ opts = @tls_options.merge(min_version: min_version, max_version: max_version)
1543
+ @d.server_create_tls(:s, @port, tls_options: opts) do |data, conn|
1544
+ end
1545
+ assert_raise(OpenSSL::SSL::SSLError, Errno::ECONNRESET) {
1546
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path, version: :'TLS1') do |sock|
1547
+ end
1548
+ }
1549
+ [min_version, max_version].each { |ver|
1550
+ assert_nothing_raised {
1551
+ open_tls_session('127.0.0.1', @port, cert_path: @cert_path, version: ver) do |sock|
1552
+ end
1553
+ }
1554
+ }
1555
+ end
1556
+ end
1557
+ end
1558
+
1559
+ sub_test_case '#server_create_unix' do
1560
+ # not implemented yet
1561
+
1562
+ # test 'can accept all keyword arguments valid for unix server'
1563
+ # test 'creates a unix server just to read data'
1564
+ # test 'creates a unix server to read and write data'
1565
+
1566
+ # test 'raises error if plugin registers data callback for connection object from #server_create'
1567
+ # test 'can call write_complete callback if registered'
1568
+ # test 'can call close callback if registered'
1569
+ end
1570
+
1571
+ def open_client(proto, addr, port)
1572
+ client = case proto
1573
+ when :tcp
1574
+ TCPSocket.open(addr, port)
1575
+ when :tls
1576
+ c = OpenSSL::SSL::SSLSocket.new(TCPSocket.open(addr, port))
1577
+ c.sync_close = true
1578
+ c.connect
1579
+ else
1580
+ raise ArgumentError, "unknown proto:#{proto}"
1581
+ end
1582
+ yield client
1583
+ ensure
1584
+ client.close rescue nil
1585
+ end
1586
+
1587
+ # run tests for tcp, tls and unix
1588
+ sub_test_case '#server_create_connection' do
1589
+ test 'raise error if udp is specified in proto' do
1590
+ assert_raise(ArgumentError.new("BUG: cannot create connection for UDP")) do
1591
+ @d.server_create_connection(:myserver, @port, proto: :udp){|c| c }
1592
+ end
1593
+ end
1594
+
1595
+ # def server_create_connection(title, port, proto: :tcp, bind: '0.0.0.0', shared: true, tls_options: nil, resolve_name: false, linger_timeout: 0, backlog: nil, &block)
1596
+ protocols = {
1597
+ 'tcp' => [:tcp, {}],
1598
+ 'tls' => [:tls, {tls_options: {insecure: true}}],
1599
+ # 'unix' => [:unix, {path: ""}],
1600
+ }
1601
+
1602
+ data(protocols)
1603
+ test 'raise error if block argument is not specified or too many' do |(proto, kwargs)|
1604
+ empty_block = ->(){}
1605
+ assert_raise(ArgumentError.new("BUG: block must have just one argument")) do
1606
+ @d.server_create_connection(:myserver, @port, proto: proto, **kwargs, &empty_block)
1607
+ end
1608
+ assert_raise(ArgumentError.new("BUG: block must have just one argument")) do
1609
+ @d.server_create_connection(:myserver, @port, proto: proto, **kwargs){|conn, what_is_this| [conn, what_is_this] }
1610
+ end
1611
+ end
1612
+
1613
+ data(protocols)
1614
+ test 'does not resolve name of client address in default' do |(proto, kwargs)|
1615
+ received = ""
1616
+ sources = []
1617
+ @d.server_create_connection(:s, @port, proto: proto, **kwargs) do |conn|
1618
+ sources << conn.remote_host
1619
+ conn.data do |d|
1620
+ received << d
1621
+ end
1622
+ end
1623
+ 3.times do
1624
+ open_client(proto, "127.0.0.1", @port) do |sock|
1625
+ sock.puts "yay"
1626
+ end
1627
+ end
1628
+ waiting(10){ sleep 0.1 until received.bytesize == 12 }
1629
+ assert_equal "yay\nyay\nyay\n", received
1630
+ assert{ sources.all?{|s| s == "127.0.0.1" } }
1631
+ end
1632
+
1633
+ data(protocols)
1634
+ test 'does resolve name of client address if resolve_name is true' do |(proto, kwargs)|
1635
+ hostname = Socket.getnameinfo([nil, nil, nil, "127.0.0.1"])[0]
1636
+
1637
+ received = ""
1638
+ sources = []
1639
+ @d.server_create_connection(:s, @port, proto: proto, resolve_name: true, **kwargs) do |conn|
1640
+ sources << conn.remote_host
1641
+ conn.data do |d|
1642
+ received << d
1643
+ end
1644
+ end
1645
+ 3.times do
1646
+ open_client(proto, "127.0.0.1", @port) do |sock|
1647
+ sock.puts "yay"
1648
+ end
1649
+ end
1650
+ waiting(10){ sleep 0.1 until received.bytesize == 12 }
1651
+ assert_equal "yay\nyay\nyay\n", received
1652
+ assert{ sources.all?{|s| s == hostname } }
1653
+ end
1654
+
1655
+ data(protocols)
1656
+ test 'creates a server to provide connection, which can read, write and close' do |(proto, kwargs)|
1657
+ lines = []
1658
+ buffer = ""
1659
+ @d.server_create_connection(:s, @port, proto: proto, **kwargs) do |conn|
1660
+ conn.data do |d|
1661
+ buffer << d
1662
+ if buffer == "x"
1663
+ buffer.slice!(0, 1)
1664
+ conn.close
1665
+ end
1666
+ if idx = buffer.index("\n")
1667
+ lines << buffer.slice!(0, idx + 1)
1668
+ conn.write "foo!\n"
1669
+ end
1670
+ end
1671
+ end
1672
+ replied = []
1673
+ disconnecteds = []
1674
+ 3.times do |i|
1675
+ open_client(proto, "127.0.0.1", @port) do |sock|
1676
+ sock.puts "yay"
1677
+ while line = sock.readline
1678
+ replied << line
1679
+ break
1680
+ end
1681
+ sock.write "x"
1682
+ connection_closed = false
1683
+ begin
1684
+ data = sock.read
1685
+ if data.empty?
1686
+ connection_closed = true
1687
+ end
1688
+ rescue => e
1689
+ if e.is_a?(Errno::ECONNRESET)
1690
+ connection_closed = true
1691
+ end
1692
+ ensure
1693
+ disconnecteds << connection_closed
1694
+ end
1695
+ end
1696
+ end
1697
+ waiting(10){ sleep 0.1 until lines.size == 3 }
1698
+ waiting(10){ sleep 0.1 until replied.size == 3 }
1699
+ waiting(10){ sleep 0.1 until disconnecteds.size == 3 }
1700
+ assert_equal ["yay\n", "yay\n", "yay\n"], lines
1701
+ assert_equal ["foo!\n", "foo!\n", "foo!\n"], replied
1702
+ assert_equal [true, true, true], disconnecteds
1703
+ end
1704
+
1705
+ data(protocols)
1706
+ test 'creates a server to provide connection, which accepts callbacks for data, write_complete, and close' do |(proto, kwargs)|
1707
+ lines = []
1708
+ buffer = ""
1709
+ written = 0
1710
+ closed = 0
1711
+ @d.server_create_connection(:s, @port, proto: proto, **kwargs) do |conn|
1712
+ conn.on(:write_complete){|_conn| written += 1 }
1713
+ conn.on(:close){|_conn| closed += 1 }
1714
+ conn.on(:data) do |d|
1715
+ buffer << d
1716
+ if idx = buffer.index("\n")
1717
+ lines << buffer.slice!(0, idx + 1)
1718
+ conn.write "foo!\n"
1719
+ end
1720
+ end
1721
+ end
1722
+ replied = []
1723
+ 3.times do
1724
+ open_client(proto, "127.0.0.1", @port) do |sock|
1725
+ sock.puts "yay"
1726
+ while line = sock.readline
1727
+ replied << line
1728
+ break
1729
+ end
1730
+ end # TCP socket is closed here
1731
+ end
1732
+ waiting(10){ sleep 0.1 until lines.size == 3 }
1733
+ waiting(10){ sleep 0.1 until replied.size == 3 }
1734
+ waiting(10){ sleep 0.1 until closed == 3 }
1735
+ assert_equal ["yay\n", "yay\n", "yay\n"], lines
1736
+ assert_equal 3, written
1737
+ assert_equal 3, closed
1738
+ assert_equal ["foo!\n", "foo!\n", "foo!\n"], replied
1739
+ end
1740
+
1741
+ data(protocols)
1742
+ test 'creates a server, and does not leak connections' do |(proto, kwargs)|
1743
+ buffer = ""
1744
+ closed = 0
1745
+ @d.server_create_connection(:s, @port, proto: proto, **kwargs) do |conn|
1746
+ conn.on(:close){|_c| closed += 1 }
1747
+ conn.on(:data) do |d|
1748
+ buffer << d
1749
+ end
1750
+ end
1751
+ 3.times do
1752
+ open_client(proto, "127.0.0.1", @port) do |sock|
1753
+ sock.puts "yay"
1754
+ end
1755
+ end
1756
+ waiting(10){ sleep 0.1 until buffer.bytesize == 12 }
1757
+ waiting(10){ sleep 0.1 until closed == 3 }
1758
+ assert_equal 0, @d.instance_eval{ @_server_connections.size }
1759
+ end
1760
+
1761
+ data(protocols)
1762
+ test 'will refuse more connect requests after stop, but read data from sockets already connected, in non-shared server' do |(proto, kwargs)|
1763
+ connected = false
1764
+ begin
1765
+ open_client(proto, "127.0.0.1", @port) do |sock|
1766
+ # expected behavior is connection refused...
1767
+ connected = true
1768
+ end
1769
+ rescue
1770
+ end
1771
+
1772
+ assert_false connected
1773
+
1774
+ received = ""
1775
+ @d.server_create_connection(:s, @port, proto: proto, shared: false, **kwargs) do |conn|
1776
+ conn.on(:data) do |data|
1777
+ received << data
1778
+ conn.write "ack\n"
1779
+ end
1780
+ end
1781
+
1782
+ th0 = Thread.new do
1783
+ open_client(proto, "127.0.0.1", @port) do |sock|
1784
+ sock.puts "yay"
1785
+ sock.readline
1786
+ end
1787
+ end
1788
+
1789
+ value0 = waiting(5){ th0.value }
1790
+ assert_equal "ack\n", value0
1791
+
1792
+ stopped = false
1793
+ sleeping = false
1794
+ ending = false
1795
+
1796
+ th1 = Thread.new do
1797
+ open_client(proto, "127.0.0.1", @port) do |sock|
1798
+ sleeping = true
1799
+ sleep 0.1 until stopped
1800
+ sock.puts "yay"
1801
+ res = sock.readline
1802
+ ending = true
1803
+ res
1804
+ end
1805
+ end
1806
+
1807
+ sleep 0.1 until sleeping
1808
+
1809
+ @d.stop
1810
+ assert @d.stopped?
1811
+ stopped = true
1812
+
1813
+ sleep 0.1 until ending
1814
+
1815
+ @d.before_shutdown
1816
+ @d.shutdown
1817
+
1818
+ th2 = Thread.new do
1819
+ begin
1820
+ open_client(proto, "127.0.0.1", @port) do |sock|
1821
+ sock.puts "foo"
1822
+ end
1823
+ false # failed
1824
+ rescue
1825
+ true # success
1826
+ end
1827
+ end
1828
+
1829
+ value1 = waiting(5){ th1.value }
1830
+ value2 = waiting(5){ th2.value }
1831
+
1832
+ assert_equal "yay\nyay\n", received
1833
+ assert_equal "ack\n", value1
1834
+ assert value2, "should be truthy value to show connection was correctly refused"
1835
+ end
1836
+
1837
+ test 'can keep connections alive for tcp/tls if keepalive specified' do
1838
+ # pend "not implemented yet"
1839
+ end
1840
+ end
1841
+ end