fluentd222 1.16.2-x86_64-linux

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