fluentd 1.14.4-x64-mingw-ucrt

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

Potentially problematic release.


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

Files changed (558) hide show
  1. checksums.yaml +7 -0
  2. data/.deepsource.toml +13 -0
  3. data/.drone.yml +35 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.yaml +70 -0
  5. data/.github/ISSUE_TEMPLATE/config.yml +5 -0
  6. data/.github/ISSUE_TEMPLATE/feature_request.yaml +38 -0
  7. data/.github/ISSUE_TEMPLATE.md +17 -0
  8. data/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  9. data/.github/workflows/issue-auto-closer.yml +12 -0
  10. data/.github/workflows/linux-test.yaml +36 -0
  11. data/.github/workflows/macos-test.yaml +30 -0
  12. data/.github/workflows/stale-actions.yml +22 -0
  13. data/.github/workflows/windows-test.yaml +46 -0
  14. data/.gitignore +30 -0
  15. data/.gitlab-ci.yml +103 -0
  16. data/ADOPTERS.md +5 -0
  17. data/AUTHORS +2 -0
  18. data/CHANGELOG.md +2409 -0
  19. data/CONTRIBUTING.md +45 -0
  20. data/GOVERNANCE.md +55 -0
  21. data/Gemfile +9 -0
  22. data/GithubWorkflow.md +78 -0
  23. data/LICENSE +202 -0
  24. data/MAINTAINERS.md +11 -0
  25. data/README.md +97 -0
  26. data/Rakefile +79 -0
  27. data/SECURITY.md +18 -0
  28. data/bin/fluent-binlog-reader +7 -0
  29. data/bin/fluent-ca-generate +6 -0
  30. data/bin/fluent-cap-ctl +7 -0
  31. data/bin/fluent-cat +5 -0
  32. data/bin/fluent-ctl +7 -0
  33. data/bin/fluent-debug +5 -0
  34. data/bin/fluent-gem +9 -0
  35. data/bin/fluent-plugin-config-format +5 -0
  36. data/bin/fluent-plugin-generate +5 -0
  37. data/bin/fluentd +15 -0
  38. data/code-of-conduct.md +3 -0
  39. data/docs/SECURITY_AUDIT.pdf +0 -0
  40. data/example/copy_roundrobin.conf +39 -0
  41. data/example/counter.conf +18 -0
  42. data/example/filter_stdout.conf +22 -0
  43. data/example/in_forward.conf +14 -0
  44. data/example/in_forward_client.conf +37 -0
  45. data/example/in_forward_shared_key.conf +15 -0
  46. data/example/in_forward_tls.conf +14 -0
  47. data/example/in_forward_users.conf +24 -0
  48. data/example/in_forward_workers.conf +21 -0
  49. data/example/in_http.conf +16 -0
  50. data/example/in_out_forward.conf +17 -0
  51. data/example/in_sample_blocks.conf +17 -0
  52. data/example/in_sample_with_compression.conf +23 -0
  53. data/example/in_syslog.conf +15 -0
  54. data/example/in_tail.conf +14 -0
  55. data/example/in_tcp.conf +13 -0
  56. data/example/in_udp.conf +13 -0
  57. data/example/logevents.conf +25 -0
  58. data/example/multi_filters.conf +61 -0
  59. data/example/out_copy.conf +20 -0
  60. data/example/out_exec_filter.conf +42 -0
  61. data/example/out_file.conf +13 -0
  62. data/example/out_forward.conf +35 -0
  63. data/example/out_forward_buf_file.conf +23 -0
  64. data/example/out_forward_client.conf +109 -0
  65. data/example/out_forward_heartbeat_none.conf +16 -0
  66. data/example/out_forward_sd.conf +17 -0
  67. data/example/out_forward_shared_key.conf +36 -0
  68. data/example/out_forward_tls.conf +18 -0
  69. data/example/out_forward_users.conf +65 -0
  70. data/example/out_null.conf +36 -0
  71. data/example/sd.yaml +8 -0
  72. data/example/secondary_file.conf +42 -0
  73. data/example/suppress_config_dump.conf +7 -0
  74. data/example/v0_12_filter.conf +78 -0
  75. data/example/v1_literal_example.conf +36 -0
  76. data/example/worker_section.conf +36 -0
  77. data/fluent.conf +139 -0
  78. data/fluentd.gemspec +55 -0
  79. data/lib/fluent/agent.rb +168 -0
  80. data/lib/fluent/capability.rb +87 -0
  81. data/lib/fluent/clock.rb +66 -0
  82. data/lib/fluent/command/binlog_reader.rb +244 -0
  83. data/lib/fluent/command/bundler_injection.rb +45 -0
  84. data/lib/fluent/command/ca_generate.rb +184 -0
  85. data/lib/fluent/command/cap_ctl.rb +174 -0
  86. data/lib/fluent/command/cat.rb +365 -0
  87. data/lib/fluent/command/ctl.rb +177 -0
  88. data/lib/fluent/command/debug.rb +103 -0
  89. data/lib/fluent/command/fluentd.rb +374 -0
  90. data/lib/fluent/command/plugin_config_formatter.rb +308 -0
  91. data/lib/fluent/command/plugin_generator.rb +365 -0
  92. data/lib/fluent/compat/call_super_mixin.rb +76 -0
  93. data/lib/fluent/compat/detach_process_mixin.rb +33 -0
  94. data/lib/fluent/compat/exec_util.rb +129 -0
  95. data/lib/fluent/compat/file_util.rb +54 -0
  96. data/lib/fluent/compat/filter.rb +68 -0
  97. data/lib/fluent/compat/formatter.rb +111 -0
  98. data/lib/fluent/compat/formatter_utils.rb +85 -0
  99. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  100. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  101. data/lib/fluent/compat/input.rb +49 -0
  102. data/lib/fluent/compat/output.rb +721 -0
  103. data/lib/fluent/compat/output_chain.rb +60 -0
  104. data/lib/fluent/compat/parser.rb +310 -0
  105. data/lib/fluent/compat/parser_utils.rb +40 -0
  106. data/lib/fluent/compat/propagate_default.rb +62 -0
  107. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  108. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  109. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  110. data/lib/fluent/compat/socket_util.rb +165 -0
  111. data/lib/fluent/compat/string_util.rb +34 -0
  112. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  113. data/lib/fluent/compat/type_converter.rb +90 -0
  114. data/lib/fluent/config/basic_parser.rb +123 -0
  115. data/lib/fluent/config/configure_proxy.rb +424 -0
  116. data/lib/fluent/config/dsl.rb +152 -0
  117. data/lib/fluent/config/element.rb +265 -0
  118. data/lib/fluent/config/error.rb +32 -0
  119. data/lib/fluent/config/literal_parser.rb +286 -0
  120. data/lib/fluent/config/parser.rb +107 -0
  121. data/lib/fluent/config/section.rb +272 -0
  122. data/lib/fluent/config/types.rb +249 -0
  123. data/lib/fluent/config/v1_parser.rb +192 -0
  124. data/lib/fluent/config.rb +76 -0
  125. data/lib/fluent/configurable.rb +201 -0
  126. data/lib/fluent/counter/base_socket.rb +44 -0
  127. data/lib/fluent/counter/client.rb +297 -0
  128. data/lib/fluent/counter/error.rb +86 -0
  129. data/lib/fluent/counter/mutex_hash.rb +163 -0
  130. data/lib/fluent/counter/server.rb +273 -0
  131. data/lib/fluent/counter/store.rb +205 -0
  132. data/lib/fluent/counter/validator.rb +145 -0
  133. data/lib/fluent/counter.rb +23 -0
  134. data/lib/fluent/daemon.rb +15 -0
  135. data/lib/fluent/daemonizer.rb +88 -0
  136. data/lib/fluent/engine.rb +253 -0
  137. data/lib/fluent/env.rb +40 -0
  138. data/lib/fluent/error.rb +34 -0
  139. data/lib/fluent/event.rb +326 -0
  140. data/lib/fluent/event_router.rb +297 -0
  141. data/lib/fluent/ext_monitor_require.rb +28 -0
  142. data/lib/fluent/filter.rb +21 -0
  143. data/lib/fluent/fluent_log_event_router.rb +141 -0
  144. data/lib/fluent/formatter.rb +23 -0
  145. data/lib/fluent/input.rb +21 -0
  146. data/lib/fluent/label.rb +46 -0
  147. data/lib/fluent/load.rb +34 -0
  148. data/lib/fluent/log.rb +713 -0
  149. data/lib/fluent/match.rb +187 -0
  150. data/lib/fluent/mixin.rb +31 -0
  151. data/lib/fluent/msgpack_factory.rb +106 -0
  152. data/lib/fluent/oj_options.rb +62 -0
  153. data/lib/fluent/output.rb +29 -0
  154. data/lib/fluent/output_chain.rb +23 -0
  155. data/lib/fluent/parser.rb +23 -0
  156. data/lib/fluent/plugin/bare_output.rb +104 -0
  157. data/lib/fluent/plugin/base.rb +197 -0
  158. data/lib/fluent/plugin/buf_file.rb +213 -0
  159. data/lib/fluent/plugin/buf_file_single.rb +225 -0
  160. data/lib/fluent/plugin/buf_memory.rb +34 -0
  161. data/lib/fluent/plugin/buffer/chunk.rb +240 -0
  162. data/lib/fluent/plugin/buffer/file_chunk.rb +413 -0
  163. data/lib/fluent/plugin/buffer/file_single_chunk.rb +311 -0
  164. data/lib/fluent/plugin/buffer/memory_chunk.rb +91 -0
  165. data/lib/fluent/plugin/buffer.rb +918 -0
  166. data/lib/fluent/plugin/compressable.rb +96 -0
  167. data/lib/fluent/plugin/exec_util.rb +22 -0
  168. data/lib/fluent/plugin/file_util.rb +22 -0
  169. data/lib/fluent/plugin/file_wrapper.rb +187 -0
  170. data/lib/fluent/plugin/filter.rb +127 -0
  171. data/lib/fluent/plugin/filter_grep.rb +189 -0
  172. data/lib/fluent/plugin/filter_parser.rb +130 -0
  173. data/lib/fluent/plugin/filter_record_transformer.rb +324 -0
  174. data/lib/fluent/plugin/filter_stdout.rb +53 -0
  175. data/lib/fluent/plugin/formatter.rb +75 -0
  176. data/lib/fluent/plugin/formatter_csv.rb +78 -0
  177. data/lib/fluent/plugin/formatter_hash.rb +35 -0
  178. data/lib/fluent/plugin/formatter_json.rb +59 -0
  179. data/lib/fluent/plugin/formatter_ltsv.rb +44 -0
  180. data/lib/fluent/plugin/formatter_msgpack.rb +33 -0
  181. data/lib/fluent/plugin/formatter_out_file.rb +53 -0
  182. data/lib/fluent/plugin/formatter_single_value.rb +36 -0
  183. data/lib/fluent/plugin/formatter_stdout.rb +76 -0
  184. data/lib/fluent/plugin/formatter_tsv.rb +40 -0
  185. data/lib/fluent/plugin/in_debug_agent.rb +71 -0
  186. data/lib/fluent/plugin/in_dummy.rb +18 -0
  187. data/lib/fluent/plugin/in_exec.rb +110 -0
  188. data/lib/fluent/plugin/in_forward.rb +473 -0
  189. data/lib/fluent/plugin/in_gc_stat.rb +72 -0
  190. data/lib/fluent/plugin/in_http.rb +667 -0
  191. data/lib/fluent/plugin/in_monitor_agent.rb +412 -0
  192. data/lib/fluent/plugin/in_object_space.rb +93 -0
  193. data/lib/fluent/plugin/in_sample.rb +141 -0
  194. data/lib/fluent/plugin/in_syslog.rb +276 -0
  195. data/lib/fluent/plugin/in_tail/position_file.rb +269 -0
  196. data/lib/fluent/plugin/in_tail.rb +1228 -0
  197. data/lib/fluent/plugin/in_tcp.rb +181 -0
  198. data/lib/fluent/plugin/in_udp.rb +92 -0
  199. data/lib/fluent/plugin/in_unix.rb +195 -0
  200. data/lib/fluent/plugin/input.rb +75 -0
  201. data/lib/fluent/plugin/metrics.rb +119 -0
  202. data/lib/fluent/plugin/metrics_local.rb +96 -0
  203. data/lib/fluent/plugin/multi_output.rb +195 -0
  204. data/lib/fluent/plugin/out_copy.rb +120 -0
  205. data/lib/fluent/plugin/out_exec.rb +105 -0
  206. data/lib/fluent/plugin/out_exec_filter.rb +319 -0
  207. data/lib/fluent/plugin/out_file.rb +334 -0
  208. data/lib/fluent/plugin/out_forward/ack_handler.rb +161 -0
  209. data/lib/fluent/plugin/out_forward/connection_manager.rb +113 -0
  210. data/lib/fluent/plugin/out_forward/error.rb +28 -0
  211. data/lib/fluent/plugin/out_forward/failure_detector.rb +84 -0
  212. data/lib/fluent/plugin/out_forward/handshake_protocol.rb +125 -0
  213. data/lib/fluent/plugin/out_forward/load_balancer.rb +114 -0
  214. data/lib/fluent/plugin/out_forward/socket_cache.rb +140 -0
  215. data/lib/fluent/plugin/out_forward.rb +826 -0
  216. data/lib/fluent/plugin/out_http.rb +275 -0
  217. data/lib/fluent/plugin/out_null.rb +74 -0
  218. data/lib/fluent/plugin/out_relabel.rb +32 -0
  219. data/lib/fluent/plugin/out_roundrobin.rb +84 -0
  220. data/lib/fluent/plugin/out_secondary_file.rb +131 -0
  221. data/lib/fluent/plugin/out_stdout.rb +74 -0
  222. data/lib/fluent/plugin/out_stream.rb +130 -0
  223. data/lib/fluent/plugin/output.rb +1556 -0
  224. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  225. data/lib/fluent/plugin/parser.rb +275 -0
  226. data/lib/fluent/plugin/parser_apache.rb +28 -0
  227. data/lib/fluent/plugin/parser_apache2.rb +88 -0
  228. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  229. data/lib/fluent/plugin/parser_csv.rb +114 -0
  230. data/lib/fluent/plugin/parser_json.rb +96 -0
  231. data/lib/fluent/plugin/parser_ltsv.rb +51 -0
  232. data/lib/fluent/plugin/parser_msgpack.rb +50 -0
  233. data/lib/fluent/plugin/parser_multiline.rb +152 -0
  234. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  235. data/lib/fluent/plugin/parser_none.rb +36 -0
  236. data/lib/fluent/plugin/parser_regexp.rb +68 -0
  237. data/lib/fluent/plugin/parser_syslog.rb +496 -0
  238. data/lib/fluent/plugin/parser_tsv.rb +42 -0
  239. data/lib/fluent/plugin/sd_file.rb +156 -0
  240. data/lib/fluent/plugin/sd_srv.rb +135 -0
  241. data/lib/fluent/plugin/sd_static.rb +58 -0
  242. data/lib/fluent/plugin/service_discovery.rb +65 -0
  243. data/lib/fluent/plugin/socket_util.rb +22 -0
  244. data/lib/fluent/plugin/storage.rb +84 -0
  245. data/lib/fluent/plugin/storage_local.rb +162 -0
  246. data/lib/fluent/plugin/string_util.rb +22 -0
  247. data/lib/fluent/plugin.rb +206 -0
  248. data/lib/fluent/plugin_helper/cert_option.rb +191 -0
  249. data/lib/fluent/plugin_helper/child_process.rb +366 -0
  250. data/lib/fluent/plugin_helper/compat_parameters.rb +343 -0
  251. data/lib/fluent/plugin_helper/counter.rb +51 -0
  252. data/lib/fluent/plugin_helper/event_emitter.rb +100 -0
  253. data/lib/fluent/plugin_helper/event_loop.rb +170 -0
  254. data/lib/fluent/plugin_helper/extract.rb +104 -0
  255. data/lib/fluent/plugin_helper/formatter.rb +147 -0
  256. data/lib/fluent/plugin_helper/http_server/app.rb +79 -0
  257. data/lib/fluent/plugin_helper/http_server/compat/server.rb +92 -0
  258. data/lib/fluent/plugin_helper/http_server/compat/ssl_context_extractor.rb +52 -0
  259. data/lib/fluent/plugin_helper/http_server/compat/webrick_handler.rb +58 -0
  260. data/lib/fluent/plugin_helper/http_server/methods.rb +35 -0
  261. data/lib/fluent/plugin_helper/http_server/request.rb +42 -0
  262. data/lib/fluent/plugin_helper/http_server/router.rb +54 -0
  263. data/lib/fluent/plugin_helper/http_server/server.rb +93 -0
  264. data/lib/fluent/plugin_helper/http_server/ssl_context_builder.rb +41 -0
  265. data/lib/fluent/plugin_helper/http_server.rb +135 -0
  266. data/lib/fluent/plugin_helper/inject.rb +154 -0
  267. data/lib/fluent/plugin_helper/metrics.rb +129 -0
  268. data/lib/fluent/plugin_helper/parser.rb +147 -0
  269. data/lib/fluent/plugin_helper/record_accessor.rb +207 -0
  270. data/lib/fluent/plugin_helper/retry_state.rb +209 -0
  271. data/lib/fluent/plugin_helper/server.rb +801 -0
  272. data/lib/fluent/plugin_helper/service_discovery/manager.rb +146 -0
  273. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  274. data/lib/fluent/plugin_helper/service_discovery.rb +125 -0
  275. data/lib/fluent/plugin_helper/socket.rb +277 -0
  276. data/lib/fluent/plugin_helper/socket_option.rb +98 -0
  277. data/lib/fluent/plugin_helper/storage.rb +349 -0
  278. data/lib/fluent/plugin_helper/thread.rb +180 -0
  279. data/lib/fluent/plugin_helper/timer.rb +92 -0
  280. data/lib/fluent/plugin_helper.rb +75 -0
  281. data/lib/fluent/plugin_id.rb +93 -0
  282. data/lib/fluent/process.rb +22 -0
  283. data/lib/fluent/registry.rb +116 -0
  284. data/lib/fluent/root_agent.rb +372 -0
  285. data/lib/fluent/rpc.rb +94 -0
  286. data/lib/fluent/static_config_analysis.rb +194 -0
  287. data/lib/fluent/supervisor.rb +1054 -0
  288. data/lib/fluent/system_config.rb +187 -0
  289. data/lib/fluent/test/base.rb +78 -0
  290. data/lib/fluent/test/driver/base.rb +225 -0
  291. data/lib/fluent/test/driver/base_owned.rb +83 -0
  292. data/lib/fluent/test/driver/base_owner.rb +135 -0
  293. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  294. data/lib/fluent/test/driver/filter.rb +57 -0
  295. data/lib/fluent/test/driver/formatter.rb +30 -0
  296. data/lib/fluent/test/driver/input.rb +31 -0
  297. data/lib/fluent/test/driver/multi_output.rb +53 -0
  298. data/lib/fluent/test/driver/output.rb +102 -0
  299. data/lib/fluent/test/driver/parser.rb +30 -0
  300. data/lib/fluent/test/driver/storage.rb +30 -0
  301. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  302. data/lib/fluent/test/filter_test.rb +77 -0
  303. data/lib/fluent/test/formatter_test.rb +65 -0
  304. data/lib/fluent/test/helpers.rb +134 -0
  305. data/lib/fluent/test/input_test.rb +174 -0
  306. data/lib/fluent/test/log.rb +79 -0
  307. data/lib/fluent/test/output_test.rb +156 -0
  308. data/lib/fluent/test/parser_test.rb +70 -0
  309. data/lib/fluent/test/startup_shutdown.rb +46 -0
  310. data/lib/fluent/test.rb +58 -0
  311. data/lib/fluent/time.rb +512 -0
  312. data/lib/fluent/timezone.rb +171 -0
  313. data/lib/fluent/tls.rb +81 -0
  314. data/lib/fluent/unique_id.rb +39 -0
  315. data/lib/fluent/variable_store.rb +40 -0
  316. data/lib/fluent/version.rb +21 -0
  317. data/lib/fluent/winsvc.rb +103 -0
  318. data/templates/new_gem/Gemfile +3 -0
  319. data/templates/new_gem/README.md.erb +43 -0
  320. data/templates/new_gem/Rakefile +13 -0
  321. data/templates/new_gem/fluent-plugin.gemspec.erb +27 -0
  322. data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
  323. data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
  324. data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
  325. data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
  326. data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
  327. data/templates/new_gem/lib/fluent/plugin/storage.rb.erb +40 -0
  328. data/templates/new_gem/test/helper.rb.erb +8 -0
  329. data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
  330. data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
  331. data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
  332. data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
  333. data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
  334. data/templates/new_gem/test/plugin/test_storage.rb.erb +18 -0
  335. data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
  336. data/templates/plugin_config_formatter/param.md-table.erb +10 -0
  337. data/templates/plugin_config_formatter/param.md.erb +34 -0
  338. data/templates/plugin_config_formatter/section.md.erb +12 -0
  339. data/test/command/test_binlog_reader.rb +362 -0
  340. data/test/command/test_ca_generate.rb +70 -0
  341. data/test/command/test_cap_ctl.rb +100 -0
  342. data/test/command/test_cat.rb +128 -0
  343. data/test/command/test_ctl.rb +57 -0
  344. data/test/command/test_fluentd.rb +1106 -0
  345. data/test/command/test_plugin_config_formatter.rb +398 -0
  346. data/test/command/test_plugin_generator.rb +109 -0
  347. data/test/compat/test_calls_super.rb +166 -0
  348. data/test/compat/test_parser.rb +92 -0
  349. data/test/config/assertions.rb +42 -0
  350. data/test/config/test_config_parser.rb +551 -0
  351. data/test/config/test_configurable.rb +1784 -0
  352. data/test/config/test_configure_proxy.rb +604 -0
  353. data/test/config/test_dsl.rb +415 -0
  354. data/test/config/test_element.rb +518 -0
  355. data/test/config/test_literal_parser.rb +309 -0
  356. data/test/config/test_plugin_configuration.rb +56 -0
  357. data/test/config/test_section.rb +191 -0
  358. data/test/config/test_system_config.rb +199 -0
  359. data/test/config/test_types.rb +408 -0
  360. data/test/counter/test_client.rb +563 -0
  361. data/test/counter/test_error.rb +44 -0
  362. data/test/counter/test_mutex_hash.rb +179 -0
  363. data/test/counter/test_server.rb +589 -0
  364. data/test/counter/test_store.rb +258 -0
  365. data/test/counter/test_validator.rb +137 -0
  366. data/test/helper.rb +155 -0
  367. data/test/helpers/fuzzy_assert.rb +89 -0
  368. data/test/helpers/process_extenstion.rb +33 -0
  369. data/test/plugin/data/2010/01/20100102-030405.log +0 -0
  370. data/test/plugin/data/2010/01/20100102-030406.log +0 -0
  371. data/test/plugin/data/2010/01/20100102.log +0 -0
  372. data/test/plugin/data/log/bar +0 -0
  373. data/test/plugin/data/log/foo/bar.log +0 -0
  374. data/test/plugin/data/log/foo/bar2 +0 -0
  375. data/test/plugin/data/log/test.log +0 -0
  376. data/test/plugin/data/sd_file/config +11 -0
  377. data/test/plugin/data/sd_file/config.json +17 -0
  378. data/test/plugin/data/sd_file/config.yaml +11 -0
  379. data/test/plugin/data/sd_file/config.yml +11 -0
  380. data/test/plugin/data/sd_file/invalid_config.yml +7 -0
  381. data/test/plugin/in_tail/test_fifo.rb +121 -0
  382. data/test/plugin/in_tail/test_io_handler.rb +140 -0
  383. data/test/plugin/in_tail/test_position_file.rb +379 -0
  384. data/test/plugin/out_forward/test_ack_handler.rb +101 -0
  385. data/test/plugin/out_forward/test_connection_manager.rb +145 -0
  386. data/test/plugin/out_forward/test_handshake_protocol.rb +112 -0
  387. data/test/plugin/out_forward/test_load_balancer.rb +106 -0
  388. data/test/plugin/out_forward/test_socket_cache.rb +149 -0
  389. data/test/plugin/test_bare_output.rb +131 -0
  390. data/test/plugin/test_base.rb +115 -0
  391. data/test/plugin/test_buf_file.rb +1275 -0
  392. data/test/plugin/test_buf_file_single.rb +833 -0
  393. data/test/plugin/test_buf_memory.rb +42 -0
  394. data/test/plugin/test_buffer.rb +1383 -0
  395. data/test/plugin/test_buffer_chunk.rb +198 -0
  396. data/test/plugin/test_buffer_file_chunk.rb +871 -0
  397. data/test/plugin/test_buffer_file_single_chunk.rb +611 -0
  398. data/test/plugin/test_buffer_memory_chunk.rb +339 -0
  399. data/test/plugin/test_compressable.rb +87 -0
  400. data/test/plugin/test_file_util.rb +96 -0
  401. data/test/plugin/test_file_wrapper.rb +126 -0
  402. data/test/plugin/test_filter.rb +368 -0
  403. data/test/plugin/test_filter_grep.rb +697 -0
  404. data/test/plugin/test_filter_parser.rb +731 -0
  405. data/test/plugin/test_filter_record_transformer.rb +577 -0
  406. data/test/plugin/test_filter_stdout.rb +207 -0
  407. data/test/plugin/test_formatter_csv.rb +136 -0
  408. data/test/plugin/test_formatter_hash.rb +38 -0
  409. data/test/plugin/test_formatter_json.rb +61 -0
  410. data/test/plugin/test_formatter_ltsv.rb +70 -0
  411. data/test/plugin/test_formatter_msgpack.rb +28 -0
  412. data/test/plugin/test_formatter_out_file.rb +116 -0
  413. data/test/plugin/test_formatter_single_value.rb +44 -0
  414. data/test/plugin/test_formatter_tsv.rb +76 -0
  415. data/test/plugin/test_in_debug_agent.rb +49 -0
  416. data/test/plugin/test_in_exec.rb +261 -0
  417. data/test/plugin/test_in_forward.rb +1180 -0
  418. data/test/plugin/test_in_gc_stat.rb +62 -0
  419. data/test/plugin/test_in_http.rb +1080 -0
  420. data/test/plugin/test_in_monitor_agent.rb +923 -0
  421. data/test/plugin/test_in_object_space.rb +60 -0
  422. data/test/plugin/test_in_sample.rb +190 -0
  423. data/test/plugin/test_in_syslog.rb +505 -0
  424. data/test/plugin/test_in_tail.rb +2363 -0
  425. data/test/plugin/test_in_tcp.rb +243 -0
  426. data/test/plugin/test_in_udp.rb +268 -0
  427. data/test/plugin/test_in_unix.rb +181 -0
  428. data/test/plugin/test_input.rb +137 -0
  429. data/test/plugin/test_metadata.rb +89 -0
  430. data/test/plugin/test_metrics.rb +294 -0
  431. data/test/plugin/test_metrics_local.rb +96 -0
  432. data/test/plugin/test_multi_output.rb +204 -0
  433. data/test/plugin/test_out_copy.rb +308 -0
  434. data/test/plugin/test_out_exec.rb +312 -0
  435. data/test/plugin/test_out_exec_filter.rb +606 -0
  436. data/test/plugin/test_out_file.rb +1037 -0
  437. data/test/plugin/test_out_forward.rb +1348 -0
  438. data/test/plugin/test_out_http.rb +428 -0
  439. data/test/plugin/test_out_null.rb +105 -0
  440. data/test/plugin/test_out_relabel.rb +28 -0
  441. data/test/plugin/test_out_roundrobin.rb +146 -0
  442. data/test/plugin/test_out_secondary_file.rb +458 -0
  443. data/test/plugin/test_out_stdout.rb +205 -0
  444. data/test/plugin/test_out_stream.rb +103 -0
  445. data/test/plugin/test_output.rb +1065 -0
  446. data/test/plugin/test_output_as_buffered.rb +2024 -0
  447. data/test/plugin/test_output_as_buffered_backup.rb +363 -0
  448. data/test/plugin/test_output_as_buffered_compress.rb +165 -0
  449. data/test/plugin/test_output_as_buffered_overflow.rb +250 -0
  450. data/test/plugin/test_output_as_buffered_retries.rb +919 -0
  451. data/test/plugin/test_output_as_buffered_secondary.rb +882 -0
  452. data/test/plugin/test_output_as_standard.rb +374 -0
  453. data/test/plugin/test_owned_by.rb +35 -0
  454. data/test/plugin/test_parser.rb +399 -0
  455. data/test/plugin/test_parser_apache.rb +42 -0
  456. data/test/plugin/test_parser_apache2.rb +47 -0
  457. data/test/plugin/test_parser_apache_error.rb +45 -0
  458. data/test/plugin/test_parser_csv.rb +200 -0
  459. data/test/plugin/test_parser_json.rb +138 -0
  460. data/test/plugin/test_parser_labeled_tsv.rb +160 -0
  461. data/test/plugin/test_parser_multiline.rb +111 -0
  462. data/test/plugin/test_parser_nginx.rb +88 -0
  463. data/test/plugin/test_parser_none.rb +52 -0
  464. data/test/plugin/test_parser_regexp.rb +289 -0
  465. data/test/plugin/test_parser_syslog.rb +650 -0
  466. data/test/plugin/test_parser_tsv.rb +122 -0
  467. data/test/plugin/test_sd_file.rb +228 -0
  468. data/test/plugin/test_sd_srv.rb +230 -0
  469. data/test/plugin/test_storage.rb +167 -0
  470. data/test/plugin/test_storage_local.rb +335 -0
  471. data/test/plugin/test_string_util.rb +26 -0
  472. data/test/plugin_helper/data/cert/cert-key.pem +27 -0
  473. data/test/plugin_helper/data/cert/cert-with-CRLF.pem +19 -0
  474. data/test/plugin_helper/data/cert/cert-with-no-newline.pem +19 -0
  475. data/test/plugin_helper/data/cert/cert.pem +19 -0
  476. data/test/plugin_helper/data/cert/cert_chains/ca-cert-key.pem +27 -0
  477. data/test/plugin_helper/data/cert/cert_chains/ca-cert.pem +20 -0
  478. data/test/plugin_helper/data/cert/cert_chains/cert-key.pem +27 -0
  479. data/test/plugin_helper/data/cert/cert_chains/cert.pem +40 -0
  480. data/test/plugin_helper/data/cert/empty.pem +0 -0
  481. data/test/plugin_helper/data/cert/generate_cert.rb +125 -0
  482. data/test/plugin_helper/data/cert/with_ca/ca-cert-key-pass.pem +30 -0
  483. data/test/plugin_helper/data/cert/with_ca/ca-cert-key.pem +27 -0
  484. data/test/plugin_helper/data/cert/with_ca/ca-cert-pass.pem +20 -0
  485. data/test/plugin_helper/data/cert/with_ca/ca-cert.pem +20 -0
  486. data/test/plugin_helper/data/cert/with_ca/cert-key-pass.pem +30 -0
  487. data/test/plugin_helper/data/cert/with_ca/cert-key.pem +27 -0
  488. data/test/plugin_helper/data/cert/with_ca/cert-pass.pem +21 -0
  489. data/test/plugin_helper/data/cert/with_ca/cert.pem +21 -0
  490. data/test/plugin_helper/data/cert/without_ca/cert-key-pass.pem +30 -0
  491. data/test/plugin_helper/data/cert/without_ca/cert-key.pem +27 -0
  492. data/test/plugin_helper/data/cert/without_ca/cert-pass.pem +20 -0
  493. data/test/plugin_helper/data/cert/without_ca/cert.pem +20 -0
  494. data/test/plugin_helper/http_server/test_app.rb +65 -0
  495. data/test/plugin_helper/http_server/test_route.rb +32 -0
  496. data/test/plugin_helper/service_discovery/test_manager.rb +93 -0
  497. data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +21 -0
  498. data/test/plugin_helper/test_cert_option.rb +25 -0
  499. data/test/plugin_helper/test_child_process.rb +840 -0
  500. data/test/plugin_helper/test_compat_parameters.rb +358 -0
  501. data/test/plugin_helper/test_event_emitter.rb +80 -0
  502. data/test/plugin_helper/test_event_loop.rb +52 -0
  503. data/test/plugin_helper/test_extract.rb +194 -0
  504. data/test/plugin_helper/test_formatter.rb +255 -0
  505. data/test/plugin_helper/test_http_server_helper.rb +372 -0
  506. data/test/plugin_helper/test_inject.rb +561 -0
  507. data/test/plugin_helper/test_metrics.rb +137 -0
  508. data/test/plugin_helper/test_parser.rb +264 -0
  509. data/test/plugin_helper/test_record_accessor.rb +238 -0
  510. data/test/plugin_helper/test_retry_state.rb +442 -0
  511. data/test/plugin_helper/test_server.rb +1823 -0
  512. data/test/plugin_helper/test_service_discovery.rb +165 -0
  513. data/test/plugin_helper/test_socket.rb +146 -0
  514. data/test/plugin_helper/test_storage.rb +542 -0
  515. data/test/plugin_helper/test_thread.rb +164 -0
  516. data/test/plugin_helper/test_timer.rb +130 -0
  517. data/test/scripts/exec_script.rb +32 -0
  518. data/test/scripts/fluent/plugin/formatter1/formatter_test1.rb +7 -0
  519. data/test/scripts/fluent/plugin/formatter2/formatter_test2.rb +7 -0
  520. data/test/scripts/fluent/plugin/formatter_known.rb +8 -0
  521. data/test/scripts/fluent/plugin/out_test.rb +81 -0
  522. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  523. data/test/scripts/fluent/plugin/parser_known.rb +4 -0
  524. data/test/test_capability.rb +74 -0
  525. data/test/test_clock.rb +164 -0
  526. data/test/test_config.rb +202 -0
  527. data/test/test_configdsl.rb +148 -0
  528. data/test/test_daemonizer.rb +91 -0
  529. data/test/test_engine.rb +203 -0
  530. data/test/test_event.rb +531 -0
  531. data/test/test_event_router.rb +331 -0
  532. data/test/test_event_time.rb +199 -0
  533. data/test/test_filter.rb +121 -0
  534. data/test/test_fluent_log_event_router.rb +99 -0
  535. data/test/test_formatter.rb +366 -0
  536. data/test/test_input.rb +31 -0
  537. data/test/test_log.rb +994 -0
  538. data/test/test_logger_initializer.rb +46 -0
  539. data/test/test_match.rb +148 -0
  540. data/test/test_mixin.rb +351 -0
  541. data/test/test_msgpack_factory.rb +18 -0
  542. data/test/test_oj_options.rb +55 -0
  543. data/test/test_output.rb +278 -0
  544. data/test/test_plugin.rb +251 -0
  545. data/test/test_plugin_classes.rb +370 -0
  546. data/test/test_plugin_helper.rb +81 -0
  547. data/test/test_plugin_id.rb +119 -0
  548. data/test/test_process.rb +14 -0
  549. data/test/test_root_agent.rb +951 -0
  550. data/test/test_static_config_analysis.rb +177 -0
  551. data/test/test_supervisor.rb +601 -0
  552. data/test/test_test_drivers.rb +136 -0
  553. data/test/test_time_formatter.rb +301 -0
  554. data/test/test_time_parser.rb +362 -0
  555. data/test/test_tls.rb +65 -0
  556. data/test/test_unique_id.rb +47 -0
  557. data/test/test_variable_store.rb +65 -0
  558. metadata +1261 -0
@@ -0,0 +1,840 @@
1
+ # coding: utf-8
2
+ require_relative '../helper'
3
+ require 'fluent/plugin_helper/child_process'
4
+ require 'fluent/plugin/base'
5
+ require 'timeout'
6
+ require 'tempfile'
7
+
8
+ class ChildProcessTest < Test::Unit::TestCase
9
+ TEST_DEADLOCK_TIMEOUT = 30
10
+ TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING = 0.1 # This may be shorter than ruby's threading timer, but work well
11
+ # @nalsh says that ruby's cpu assignments for threads are almost 200ms or so.
12
+ # Loop interval (expected that it work as specified) should be longer than it.
13
+ TEST_WAIT_INTERVAL_FOR_LOOP = 0.5
14
+
15
+ setup do
16
+ @d = Dummy.new
17
+ @d.configure(config_element())
18
+ @d.start
19
+ end
20
+
21
+ teardown do
22
+ if @d
23
+ @d.stop unless @d.stopped?
24
+ @d.shutdown unless @d.shutdown?
25
+ @d.close unless @d.closed?
26
+ @d.terminate unless @d.terminated?
27
+ @d.log.reset
28
+ end
29
+ end
30
+
31
+ class Dummy < Fluent::Plugin::TestBase
32
+ helpers :child_process
33
+ def configure(conf)
34
+ super
35
+ @_child_process_kill_timeout = 1
36
+ end
37
+ end
38
+
39
+ test 'can be instantiated' do
40
+ d1 = Dummy.new
41
+ assert d1.respond_to?(:_child_process_processes)
42
+ end
43
+
44
+ test 'can be configured and started' do
45
+ d1 = Dummy.new
46
+ assert_nothing_raised do
47
+ d1.configure(config_element())
48
+ end
49
+ assert d1.plugin_id
50
+ assert d1.log
51
+
52
+ d1.start
53
+ end
54
+
55
+ test 'can execute external command asyncronously' do
56
+ m = Mutex.new
57
+ m.lock
58
+ ary = []
59
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
60
+ ran = false
61
+ @d.child_process_execute(:t0, 'echo', arguments: ['foo', 'bar'], mode: [:read]) do |io|
62
+ m.lock
63
+ ran = true
64
+ io.read # discard
65
+ ary << 2
66
+ m.unlock
67
+ end
68
+ ary << 1
69
+ m.unlock
70
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
71
+ m.lock
72
+ m.unlock
73
+ end
74
+ assert_equal [1,2], ary
75
+ end
76
+
77
+ test 'can execute external command at just once, which finishes immediately' do
78
+ m = Mutex.new
79
+ t1 = Time.now
80
+ ary = []
81
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
82
+ ran = false
83
+ @d.child_process_execute(:t1, 'echo', arguments: ['foo', 'bar'], mode: [:read]) do |io|
84
+ m.lock
85
+ ran = true
86
+ ary << io.read
87
+ m.unlock
88
+ end
89
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
90
+ m.lock
91
+ m.unlock
92
+ end
93
+ assert{ Time.now - t1 < 4.0 }
94
+ end
95
+
96
+ test 'can execute external command at just once, which can handle both of read and write' do
97
+ m = Mutex.new
98
+ ary = []
99
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
100
+ ran = false
101
+ cmd = "ruby -e 'while !STDIN.eof? && line = STDIN.readline; puts line.chomp; STDOUT.flush rescue nil; end'"
102
+ @d.child_process_execute(:t2, cmd, mode: [:write, :read]) do |writeio, readio|
103
+ m.lock
104
+ ran = true
105
+
106
+ [[1,2],[3,4],[5,6]].each do |i,j|
107
+ writeio.write "my data#{i}\n"
108
+ writeio.write "my data#{j}\n"
109
+ writeio.flush
110
+ end
111
+ writeio.close
112
+
113
+ while line = readio.readline
114
+ ary << line
115
+ end
116
+ m.unlock
117
+ end
118
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
119
+ m.lock
120
+ m.unlock
121
+ end
122
+
123
+ assert_equal [], @d.log.out.logs
124
+ expected = (1..6).map{|i| "my data#{i}\n" }
125
+ assert_equal expected, ary
126
+ end
127
+
128
+ test 'can execute external command at just once, which can handle both of read and write. Ignore stderr message/no block' do
129
+ m = Mutex.new
130
+ ary = []
131
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
132
+ ran = false
133
+ # lots of stderr message should not be blocked and message should not be printed in test.
134
+ cmd = "ruby -e 'while !STDIN.eof? && line = STDIN.readline; STDERR.puts line.chomp * 1000; STDOUT.puts line.chomp; STDOUT.flush rescue nil; end'"
135
+ @d.child_process_execute(:t2_and_ignore_stderr, cmd, mode: [:write, :read]) do |writeio, readio|
136
+ m.lock
137
+ ran = true
138
+
139
+ [[1,2],[3,4],[5,6]].each do |i,j|
140
+ writeio.write "my data#{i}\n"
141
+ writeio.write "my data#{j}\n"
142
+ writeio.flush
143
+ end
144
+ writeio.close
145
+
146
+ while line = readio.readline
147
+ ary << line
148
+ end
149
+ m.unlock
150
+ end
151
+ begin
152
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
153
+ m.lock
154
+ rescue
155
+ ensure
156
+ m.unlock
157
+ end
158
+ end
159
+
160
+ assert_equal [], @d.log.out.logs
161
+ expected = (1..6).map{|i| "my data#{i}\n" }
162
+ assert_equal expected, ary
163
+ end
164
+
165
+ test 'can execute external command at just once, which can handle all of read, write and stderr' do
166
+ m = Mutex.new
167
+ ary1 = []
168
+ ary2 = []
169
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
170
+ ran = false
171
+ cmd = "ruby -e 'while !STDIN.eof? && line = STDIN.readline; puts line.chomp; STDOUT.flush rescue nil; STDERR.puts line.chomp; STDERR.flush rescue nil; end'"
172
+ @d.child_process_execute(:t2a, cmd, mode: [:write, :read, :stderr]) do |writeio, readio, stderrio|
173
+ m.lock
174
+ ran = true
175
+
176
+ [[1,2],[3,4],[5,6]].each do |i,j|
177
+ writeio.write "my data#{i}\n"
178
+ writeio.write "my data#{j}\n"
179
+ writeio.flush
180
+ end
181
+ writeio.close
182
+
183
+ while (line1 = readio.readline) && (line2 = stderrio.readline)
184
+ ary1 << line1
185
+ ary2 << line2
186
+ end
187
+
188
+ m.unlock
189
+ end
190
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
191
+ m.lock
192
+ m.unlock
193
+ end
194
+
195
+ assert_equal [], @d.log.out.logs
196
+ expected = (1..6).map{|i| "my data#{i}\n" }
197
+ assert_equal expected, ary1
198
+ assert_equal expected, ary2
199
+ end
200
+
201
+ test 'can execute external command at just once, which can handle both of write and read (with stderr)' do
202
+ m = Mutex.new
203
+ ary = []
204
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
205
+ ran = false
206
+ cmd = "ruby"
207
+ args = ['-e', 'while !STDIN.eof? && line = STDIN.readline; puts "[s]" + line.chomp; STDOUT.flush rescue nil; STDERR.puts "[e]" + line.chomp; STDERR.flush rescue nil; end']
208
+ @d.child_process_execute(:t2b, cmd, arguments: args, mode: [:write, :read_with_stderr]) do |writeio, readio|
209
+ m.lock
210
+ ran = true
211
+
212
+ [[1,2],[3,4],[5,6]].each do |i,j|
213
+ writeio.write "my data#{i}\n"
214
+ writeio.write "my data#{j}\n"
215
+ writeio.flush
216
+ end
217
+ writeio.close
218
+
219
+ while line = readio.readline
220
+ ary << line
221
+ end
222
+
223
+ m.unlock
224
+ end
225
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
226
+ m.lock
227
+ m.unlock
228
+ end
229
+
230
+ assert_equal [], @d.log.out.logs
231
+ expected = (1..6).map{|i| ["[s]my data#{i}\n", "[e]my data#{i}\n"] }.flatten
232
+ assert_equal expected, ary
233
+ end
234
+
235
+ test 'can execute external command at just once, which runs forever' do
236
+ ary = []
237
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
238
+ ran = false
239
+ args = ["-e", "while sleep 0.1; puts 1; STDOUT.flush; end"]
240
+ @d.child_process_execute(:t3, "ruby", arguments: args, mode: [:read]) do |io|
241
+ begin
242
+ while @d.child_process_running? && line = io.readline
243
+ ran ||= true
244
+ ary << line
245
+ end
246
+ rescue
247
+ # ignore
248
+ end
249
+ end
250
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until ran
251
+ sleep 1
252
+
253
+ @d.stop # nothing occurs
254
+ @d.shutdown
255
+ assert { ary.size >= 4 }
256
+
257
+ @d.close
258
+
259
+ @d.terminate
260
+ assert @d._child_process_processes.empty?
261
+ end
262
+ end
263
+
264
+ # In windows environment, child_process try KILL at first (because there's no SIGTERM)
265
+ test 'can execute external command just once, and can terminate it forcedly when shutdown/terminate even if it ignore SIGTERM' do
266
+ omit "SIGTERM is unavailable on Windows" if Fluent.windows?
267
+
268
+ m = Mutex.new
269
+ ary = []
270
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
271
+ ran = false
272
+ @d.child_process_execute(:t4, "ruby -e 'Signal.trap(:TERM, nil); while sleep 0.1; puts 1; STDOUT.flush rescue nil; end'", mode: [:read]) do |io|
273
+ begin
274
+ while line = io.readline
275
+ unless ran
276
+ m.lock
277
+ ran = true
278
+ end
279
+ ary << line
280
+ end
281
+ rescue
282
+ # ignore
283
+ ensure
284
+ m.unlock
285
+ end
286
+ end
287
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
288
+
289
+ assert_equal [], @d.log.out.logs
290
+
291
+ @d.stop # nothing occurs
292
+ lines1 = nil
293
+ waiting(TEST_WAIT_INTERVAL_FOR_LOOP * 3) do
294
+ lines1 = ary.size
295
+ lines1 > 1
296
+ end
297
+
298
+ pid = @d._child_process_processes.keys.first
299
+ # default value 10 is too long for test
300
+ @d.instance_eval { @_child_process_exit_timeout = 1 }
301
+ @d.shutdown
302
+ sleep TEST_WAIT_INTERVAL_FOR_LOOP
303
+ lines2 = ary.size
304
+ assert { lines2 > lines1 }
305
+ @d.close
306
+
307
+ assert_nil((Process.waitpid(pid, Process::WNOHANG) rescue nil))
308
+
309
+ @d.terminate
310
+ assert @d._child_process_processes.empty?
311
+ begin
312
+ Process.waitpid(pid)
313
+ rescue Errno::ECHILD
314
+ end
315
+ # Process successfully KILLed if test reaches here
316
+ assert true
317
+ end
318
+ end
319
+
320
+ test 'can execute external command many times, which finishes immediately' do
321
+ ary = []
322
+ arguments = ["okay"]
323
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
324
+ @d.child_process_execute(:t5, "echo", arguments: arguments, interval: 1, mode: [:read]) do |io|
325
+ ary << io.read.split("\n").map(&:chomp).join
326
+ end
327
+ sleep 2.9 # 2sec(second invocation) + 0.9sec
328
+ assert_equal [], @d.log.out.logs
329
+ @d.stop
330
+ assert_equal [], @d.log.out.logs
331
+ @d.shutdown; @d.close; @d.terminate
332
+ assert_equal 2, ary.size
333
+ end
334
+ end
335
+
336
+ test 'can execute external command many times, with leading once executed immediately' do
337
+ ary = []
338
+ arguments = ["okay"]
339
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
340
+ @d.child_process_execute(:t6, "echo", arguments: arguments, interval: 1, immediate: true, mode: [:read]) do |io|
341
+ ary << io.read.split("\n").map(&:chomp).join
342
+ end
343
+ sleep 1.9 # 1sec(second invocation) + 0.9sec
344
+ @d.stop; @d.shutdown; @d.close; @d.terminate
345
+ assert_equal 2, ary.size
346
+ assert_equal [], @d.log.out.logs
347
+ end
348
+ end
349
+
350
+ test 'does not execute long running external command in parallel in default' do
351
+ ary = []
352
+ arguments = ["-e", "10.times{ sleep #{TEST_WAIT_INTERVAL_FOR_LOOP} }"] # 5 sec
353
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
354
+ assert_equal [], @d.log.out.logs
355
+ @d.log.out.singleton_class.module_eval do
356
+ define_method(:write){|message|
357
+ raise "boo" if message.include?('test: {"test":"test"}') || message.include?('test: {"test"=>"test"}')
358
+ @logs.push message
359
+ }
360
+ end
361
+
362
+ @d.child_process_execute(:t7, "ruby", arguments: arguments, interval: 1, immediate: true, mode: [:read]) do |io|
363
+ ary << io.read.split("\n").map(&:chomp).join
364
+ end
365
+ sleep 2
366
+ assert_equal 1, @d._child_process_processes.size
367
+ @d.stop
368
+ warn_msg = '[warn]: previous child process is still running. skipped. title=:t7 command="ruby" arguments=["-e", "10.times{ sleep 0.5 }"] interval=1 parallel=false' + "\n"
369
+ logs = @d.log.out.logs
370
+ assert{ logs.first.end_with?(warn_msg) }
371
+ assert{ logs.all?{|line| line.end_with?(warn_msg) } }
372
+ @d.shutdown; @d.close; @d.terminate
373
+ assert_equal [], @d.log.out.logs
374
+ end
375
+ end
376
+
377
+ test 'can execute long running external command in parallel if specified' do
378
+ ary = []
379
+ arguments = ["-e", "10.times{ puts 'okay'; STDOUT.flush rescue nil; sleep #{TEST_WAIT_INTERVAL_FOR_LOOP} }"] # 5 sec
380
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
381
+ @d.child_process_execute(:t8, "ruby", arguments: arguments, interval: 1, immediate: true, parallel: true, mode: [:read]) do |io|
382
+ ary << io.read.split("\n").map(&:chomp).join
383
+ end
384
+ sleep 2
385
+ processes = @d._child_process_processes.size
386
+ assert { processes >= 2 && processes <= 4 }
387
+ @d.stop; @d.shutdown; @d.close; @d.terminate
388
+ assert_equal [], @d.log.out.logs
389
+ end
390
+ end
391
+
392
+ test 'execute external processes only for writing' do
393
+ m = Mutex.new
394
+ unreadable = false
395
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
396
+ ran = false
397
+ @d.child_process_execute(:t9, "ruby", arguments: ['-e', 'a=""; while b=STDIN.readline; a+=b; end'], mode: [:write]) do |io|
398
+ m.lock
399
+ ran = true
400
+ begin
401
+ io.read
402
+ rescue IOError
403
+ unreadable = true
404
+ end
405
+ 50.times do
406
+ io.write "hahaha\n"
407
+ end
408
+ m.unlock
409
+ end
410
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
411
+ m.lock
412
+ m.unlock
413
+ assert unreadable
414
+ @d.stop; @d.shutdown; @d.close; @d.terminate
415
+ assert_equal [], @d.log.out.logs
416
+ end
417
+ end
418
+
419
+ test 'execute external processes only for reading' do
420
+ m = Mutex.new
421
+ unwritable = false
422
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
423
+ ran = false
424
+ @d.child_process_execute(:t10, "ruby", arguments: ["-e", "while sleep #{TEST_WAIT_INTERVAL_FOR_LOOP}; puts 1; STDOUT.flush rescue nil; end"], mode: [:read]) do |io|
425
+ m.lock
426
+ ran = true
427
+ begin
428
+ io.write "foobar"
429
+ rescue IOError
430
+ unwritable = true
431
+ end
432
+ _data = io.readline
433
+ m.unlock
434
+ end
435
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
436
+ m.lock
437
+ m.unlock
438
+ @d.stop; @d.shutdown; @d.close; @d.terminate
439
+ assert unwritable
440
+ assert_equal [], @d.log.out.logs
441
+ end
442
+ end
443
+
444
+ test 'can control external encodings' do
445
+ m = Mutex.new
446
+ encodings = []
447
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
448
+ ran = false
449
+ @d.child_process_execute(:t11, "ruby -e 'sleep 10'", external_encoding: 'ascii-8bit') do |r, w|
450
+ m.lock
451
+ ran = true
452
+ encodings << r.external_encoding
453
+ encodings << w.external_encoding
454
+ m.unlock
455
+ end
456
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
457
+ m.lock
458
+ assert_equal Encoding::ASCII_8BIT, encodings[0]
459
+ assert_equal Encoding::ASCII_8BIT, encodings[1]
460
+ @d.stop; @d.shutdown; @d.close; @d.terminate
461
+ end
462
+ end
463
+
464
+ test 'can control internal encodings' do
465
+ m = Mutex.new
466
+ encodings = []
467
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
468
+ ran = false
469
+ @d.child_process_execute(:t12, "ruby -e 'sleep 10'", external_encoding: 'utf-8', internal_encoding: 'ascii-8bit') do |r, w|
470
+ m.lock
471
+ ran = true
472
+ encodings << r.internal_encoding
473
+ encodings << w.internal_encoding
474
+ m.unlock
475
+ end
476
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
477
+ m.lock
478
+ assert_equal Encoding::ASCII_8BIT, encodings[0]
479
+ assert_equal Encoding::ASCII_8BIT, encodings[1]
480
+ @d.stop; @d.shutdown; @d.close; @d.terminate
481
+ end
482
+ end
483
+
484
+ test 'can convert encodings from ascii-8bit to utf-8' do
485
+ m = Mutex.new
486
+ str = nil
487
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
488
+ ran = false
489
+ args = ['-e', 'STDOUT.set_encoding("ascii-8bit"); STDOUT.write "\xA4\xB5\xA4\xC8\xA4\xB7"']
490
+ @d.child_process_execute(:t13, "ruby", arguments: args, external_encoding: 'euc-jp', internal_encoding: 'windows-31j', mode: [:read]) do |io|
491
+ m.lock
492
+ ran = true
493
+ str = io.read
494
+ m.unlock
495
+ end
496
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
497
+ m.lock
498
+ assert_equal Encoding.find('windows-31j'), str.encoding
499
+ expected = "さとし".encode('windows-31j')
500
+ assert_equal expected, str
501
+ @d.stop; @d.shutdown; @d.close; @d.terminate
502
+ end
503
+ end
504
+
505
+ test 'can scrub characters without exceptions' do
506
+ m = Mutex.new
507
+ str = nil
508
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
509
+ ran = false
510
+ args = ['-e', 'STDOUT.set_encoding("ascii-8bit"); STDOUT.write "\xFF\xFF\x00\xF0\xF0"']
511
+ @d.child_process_execute(:t13a, "ruby", arguments: args, mode: [:read]) do |io|
512
+ m.lock
513
+ ran = true
514
+ str = io.read
515
+ m.unlock
516
+ end
517
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
518
+ m.lock
519
+ assert_equal Encoding.find('utf-8'), str.encoding
520
+ expected = "\xEF\xBF\xBD\xEF\xBF\xBD\x00\xEF\xBF\xBD\xEF\xBF\xBD".force_encoding("utf-8")
521
+ assert_equal expected, str
522
+ @d.stop; @d.shutdown; @d.close; @d.terminate
523
+ end
524
+ end
525
+
526
+ test 'can scrub characters without exceptions and replace specified chars' do
527
+ m = Mutex.new
528
+ str = nil
529
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
530
+ ran = false
531
+ args = ['-e', 'STDOUT.set_encoding("ascii-8bit"); STDOUT.write "\xFF\xFF\x00\xF0\xF0"']
532
+ @d.child_process_execute(:t13b, "ruby", arguments: args, mode: [:read], scrub: true, replace_string: '?') do |io|
533
+ m.lock
534
+ ran = true
535
+ str = io.read
536
+ m.unlock
537
+ end
538
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
539
+ m.lock
540
+ assert_equal Encoding.find('utf-8'), str.encoding
541
+ expected = "??\x00??".force_encoding("utf-8")
542
+ assert_equal expected, str
543
+ @d.stop; @d.shutdown; @d.close; @d.terminate
544
+ end
545
+ end
546
+
547
+ unless Fluent.windows?
548
+ test 'can specify subprocess name' do
549
+ io = IO.popen([["cat", "caaaaaaaaaaat"], '-'])
550
+ process_naming_enabled = (open("|ps opid,cmd"){|_io| _io.readlines }.select{|line| line.include?("caaaaaaaaaaat") }.size > 0)
551
+ Process.kill(:TERM, io.pid) rescue nil
552
+ io.close rescue nil
553
+
554
+ # Does TravisCI prohibit process renaming?
555
+ # This test will be passed in such environment
556
+ pend unless process_naming_enabled
557
+
558
+ m = Mutex.new
559
+ pids = []
560
+ proc_lines = []
561
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
562
+ ran = false
563
+ @d.child_process_execute(:t14, "/bin/sh", arguments:['-c', 'sleep 10; echo "hello"'], subprocess_name: "sleeeeeeeeeper", mode: [:read]) do |readio|
564
+ m.lock
565
+ ran = true
566
+ pids << @d.child_process_id
567
+ proc_lines += open("|ps opid,cmd"){|_io| _io.readlines }
568
+ m.unlock
569
+ readio.read
570
+ end
571
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
572
+ m.lock
573
+ pid = pids.first
574
+ # 16357 sleeeeeeeeeper -e sleep 10; puts "hello"
575
+ assert{ proc_lines.select{|line| line =~ /^\s*#{pid}\s/ }.first.strip.split(/\s+/)[1] == "sleeeeeeeeeper" }
576
+ @d.stop; @d.shutdown; @d.close; @d.terminate
577
+ end
578
+ end
579
+ end
580
+
581
+ test 'can set ENV variables' do
582
+ m = Mutex.new
583
+ str = nil
584
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
585
+ ran = false
586
+ args = ['-e', 'puts ENV["testing_child_process"]']
587
+ @d.child_process_execute(:t15a, "ruby", arguments: args, mode: [:read], env: {'testing_child_process' => 'Yes! True!'}) do |io|
588
+ m.lock
589
+ ran = true
590
+ str = io.read
591
+ m.unlock
592
+ end
593
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
594
+ m.lock
595
+ expected = "Yes! True!\n"
596
+ assert_equal expected, str
597
+ @d.stop; @d.shutdown; @d.close; @d.terminate
598
+ end
599
+ end
600
+
601
+ test 'can unset ENV variables of Fluentd process' do
602
+ m = Mutex.new
603
+ str = nil
604
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
605
+ current_env_path = ENV['PATH']
606
+ ran = false
607
+ args = ['-e', 'puts ENV["testing_child_process1"].to_s + ENV["testing_child_process2"].to_s']
608
+ ENV['testing_child_process1'] = "No! False!"
609
+ @d.child_process_execute(:t15b, "ruby", arguments: args, mode: [:read], unsetenv: true, env: {'testing_child_process2' => 'Yes! True!', 'PATH' => current_env_path}) do |io|
610
+ m.lock
611
+ ran = true
612
+ str = io.read
613
+ m.unlock
614
+ end
615
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
616
+ m.lock
617
+ expected = "Yes! True!\n"
618
+ assert_equal expected, str
619
+ @d.stop; @d.shutdown; @d.close; @d.terminate
620
+ end
621
+ end
622
+
623
+ unless Fluent.windows?
624
+ test 'can change working directory' do
625
+ # check my real /tmp directory (for mac)
626
+ cmd = %[|ruby -e 'Dir.chdir("/tmp"); puts Dir.pwd']
627
+ mytmpdir = open(cmd){|io| io.read.chomp }
628
+
629
+ m = Mutex.new
630
+ str = nil
631
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
632
+ ran = false
633
+ args = ['-e', 'puts Dir.pwd']
634
+ @d.child_process_execute(:t16, "ruby", arguments: args, mode: [:read], chdir: "/tmp") do |io|
635
+ m.lock
636
+ ran = true
637
+ str = io.read.chomp
638
+ m.unlock
639
+ end
640
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until m.locked? || ran
641
+ m.lock
642
+ assert_equal mytmpdir, str
643
+ @d.stop; @d.shutdown; @d.close; @d.terminate
644
+ end
645
+ end
646
+ end
647
+
648
+ sub_test_case 'on_exit_callback is specified' do
649
+ setup do
650
+ @temp = Tempfile.create("child_process_wait_with_on_exit_callback")
651
+ @temp_path = @temp.path
652
+ @temp.close
653
+ end
654
+
655
+ teardown do
656
+ File.unlink @temp_path if File.exist?(@temp_path)
657
+ end
658
+
659
+ test 'can return exit status for child process successfully exits using on_exit_callback' do
660
+ assert File.exist?(@temp_path)
661
+
662
+ block_exits = false
663
+ callback_called = false
664
+ exit_status = nil
665
+ args = ['-e', 'puts "yay"; File.unlink ARGV[0]', @temp_path]
666
+ cb = ->(status){ exit_status = status; callback_called = true }
667
+
668
+ str = nil
669
+ pid = nil
670
+ @d.child_process_execute(:st1, "ruby", arguments: args, mode: [:read], on_exit_callback: cb) do |readio|
671
+ assert !callback_called # ensure yet to be called
672
+ pid = @d.instance_eval { child_process_id }
673
+ str = readio.read.chomp
674
+ block_exits = true
675
+ end
676
+ waiting(TEST_DEADLOCK_TIMEOUT){ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING while @d.child_process_exist?(pid) } # to get exit status
677
+ waiting(TEST_DEADLOCK_TIMEOUT){ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until block_exits }
678
+ waiting(TEST_DEADLOCK_TIMEOUT){ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called }
679
+
680
+ assert callback_called
681
+ assert exit_status
682
+ assert_equal 0, exit_status.exitstatus
683
+ assert !File.exist?(@temp_path)
684
+
685
+ assert_equal "yay", str
686
+ end
687
+
688
+ test 'can return exit status with signal code for child process killed by signal using on_exit_callback' do
689
+ omit "SIGQUIT is unsupported on Windows" if Fluent.windows?
690
+
691
+ assert File.exist?(@temp_path)
692
+
693
+ block_exits = false
694
+ callback_called = false
695
+ exit_status = nil
696
+ args = ['-e', 'sleep ARGV[0].to_i; puts "yay"; File.unlink ARGV[1]', '100', @temp_path]
697
+ cb = ->(status){ exit_status = status; callback_called = true }
698
+
699
+ str = nil
700
+ pid = nil
701
+ @d.child_process_execute(:st1, "ruby", arguments: args, mode: [:read], on_exit_callback: cb) do |readio|
702
+ pid = @d.instance_eval { child_process_id }
703
+ sleep 1
704
+ Process.kill(:QUIT, pid)
705
+ str = readio.read.chomp rescue nil # empty string before EOF
706
+ block_exits = true
707
+ end
708
+ waiting(TEST_DEADLOCK_TIMEOUT){ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING while @d.child_process_exist?(pid) } # to get exit status
709
+ waiting(TEST_DEADLOCK_TIMEOUT){ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until block_exits }
710
+ waiting(TEST_DEADLOCK_TIMEOUT){ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called }
711
+
712
+ assert callback_called
713
+ assert exit_status
714
+
715
+ assert_equal nil, exit_status.exitstatus
716
+ assert_equal 3, exit_status.termsig
717
+ assert File.exist?(@temp_path)
718
+ assert_equal '', str
719
+ end
720
+
721
+ test 'calls on_exit_callback for each process exits for interval call using on_exit_callback' do
722
+ read_data_list = []
723
+ exit_status_list = []
724
+
725
+ args = ['yay']
726
+ cb = ->(status){ exit_status_list << status }
727
+
728
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
729
+ @d.child_process_execute(:st1, "echo", arguments: args, immediate: true, interval: 1, mode: [:read], on_exit_callback: cb) do |readio|
730
+ read_data_list << readio.read.chomp
731
+ end
732
+ sleep 2.5
733
+ end
734
+
735
+ assert { read_data_list.size >= 2 }
736
+ assert { exit_status_list.size >= 2 }
737
+ end
738
+
739
+ test 'waits lasting child process until wait_timeout if block is not specified' do
740
+ assert File.exist?(@temp_path)
741
+
742
+ callback_called = false
743
+ exit_status = nil
744
+ args = ['-e', 'File.unlink ARGV[0]', @temp_path]
745
+ cb = ->(status){ exit_status = status; callback_called = true }
746
+
747
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
748
+ @d.child_process_execute(:t17, "ruby", arguments: args, on_exit_callback: cb, wait_timeout: 2)
749
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
750
+ end
751
+
752
+ assert callback_called
753
+ assert exit_status
754
+ assert_equal 0, exit_status.exitstatus
755
+ assert !File.exist?(@temp_path)
756
+ end
757
+
758
+ test 'waits lasting child process until wait_timeout after block rans if block is specified' do
759
+ assert File.exist?(@temp_path)
760
+
761
+ callback_called = false
762
+ exit_status = nil
763
+ args = ['-e', 'File.unlink ARGV[0]', @temp_path]
764
+ cb = ->(status){ exit_status = status; callback_called = true }
765
+
766
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
767
+ @d.child_process_execute(:t17, "ruby", arguments: args, mode: nil, on_exit_callback: cb, wait_timeout: 10) do
768
+ sleep 1
769
+ end
770
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
771
+ end
772
+
773
+ assert callback_called
774
+ assert exit_status
775
+ assert_equal 0, exit_status.exitstatus
776
+ assert !File.exist?(@temp_path)
777
+ end
778
+
779
+ test 'kills lasting child process after wait_timeout if block is not specified' do
780
+ assert File.exist?(@temp_path)
781
+
782
+ callback_called = false
783
+ exit_status = nil
784
+ args = ['-e', 'sleep ARGV[0].to_i; File.unlink ARGV[1]', '20', @temp_path]
785
+ cb = ->(status){ exit_status = status; callback_called = true }
786
+
787
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
788
+ @d.child_process_execute(:t17, "ruby", arguments: args, on_exit_callback: cb, wait_timeout: 1)
789
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
790
+ end
791
+
792
+ assert callback_called
793
+ assert exit_status
794
+ unless Fluent.windows? # On Windows, exitstatus is always 0 and termsig is nil
795
+ assert_nil exit_status.exitstatus
796
+ assert_equal 9, exit_status.termsig # SIGKILL
797
+ end
798
+ assert File.exist?(@temp_path)
799
+ end
800
+
801
+ test 'kills lasting child process after block ran and wait_timeout expires if block is specified' do
802
+ assert File.exist?(@temp_path)
803
+
804
+ callback_called = false
805
+ exit_status = nil
806
+ args = ['-e', 'sleep ARGV[0].to_i; File.unlink ARGV[1]', '20', @temp_path]
807
+ cb = ->(status){ exit_status = status; callback_called = true }
808
+
809
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
810
+ @d.child_process_execute(:t17, "ruby", arguments: args, mode: nil, on_exit_callback: cb, wait_timeout: 1) do
811
+ sleep 1
812
+ end
813
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
814
+ end
815
+
816
+ assert callback_called
817
+ assert exit_status
818
+ unless Fluent.windows? # On Windows, exitstatus is always 0 and termsig is nil
819
+ assert_nil exit_status.exitstatus
820
+ assert_equal 9, exit_status.termsig # SIGKILL
821
+ end
822
+ assert File.exist?(@temp_path)
823
+ end
824
+
825
+ test 'execute child process writing data to stdout which is unread' do
826
+ callback_called = false
827
+ exit_status = nil
828
+ prog = "echo writing to stdout"
829
+ callback = ->(status){ exit_status = status; callback_called = true }
830
+ Timeout.timeout(TEST_DEADLOCK_TIMEOUT) do
831
+ @d.child_process_execute(:out_exec_process, prog, stderr: :connect, immediate: true, parallel: true, mode: [], wait_timeout: 1, on_exit_callback: callback)
832
+ sleep TEST_WAIT_INTERVAL_FOR_BLOCK_RUNNING until callback_called
833
+ end
834
+ assert callback_called
835
+ assert exit_status
836
+ assert exit_status.success?
837
+ assert_equal 0, exit_status.exitstatus
838
+ end
839
+ end
840
+ end