fluentd 1.14.4-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

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