fluentd-hubspot 0.14.14.1

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