dtomasgu-fluentd 1.14.7.pre.dev

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