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,1275 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin/buf_file'
3
+ require 'fluent/plugin/output'
4
+ require 'fluent/unique_id'
5
+ require 'fluent/system_config'
6
+ require 'fluent/env'
7
+
8
+ require 'msgpack'
9
+
10
+ module FluentPluginFileBufferTest
11
+ class DummyOutputPlugin < Fluent::Plugin::Output
12
+ Fluent::Plugin.register_output('buffer_file_test_output', self)
13
+ config_section :buffer do
14
+ config_set_default :@type, 'file'
15
+ end
16
+ def multi_workers_ready?
17
+ true
18
+ end
19
+ def write(chunk)
20
+ # drop
21
+ end
22
+ end
23
+ end
24
+
25
+ class FileBufferTest < Test::Unit::TestCase
26
+ def metadata(timekey: nil, tag: nil, variables: nil, seq: 0)
27
+ m = Fluent::Plugin::Buffer::Metadata.new(timekey, tag, variables)
28
+ m.seq = seq
29
+ m
30
+ end
31
+
32
+ def write_metadata_old(path, chunk_id, metadata, size, ctime, mtime)
33
+ metadata = {
34
+ timekey: metadata.timekey, tag: metadata.tag, variables: metadata.variables,
35
+ id: chunk_id,
36
+ s: size,
37
+ c: ctime,
38
+ m: mtime,
39
+ }
40
+ File.open(path, 'wb') do |f|
41
+ f.write metadata.to_msgpack
42
+ end
43
+ end
44
+
45
+ def write_metadata(path, chunk_id, metadata, size, ctime, mtime)
46
+ metadata = {
47
+ timekey: metadata.timekey, tag: metadata.tag, variables: metadata.variables,
48
+ seq: metadata.seq,
49
+ id: chunk_id,
50
+ s: size,
51
+ c: ctime,
52
+ m: mtime,
53
+ }
54
+
55
+ data = metadata.to_msgpack
56
+ size = [data.size].pack('N')
57
+ File.open(path, 'wb') do |f|
58
+ f.write(Fluent::Plugin::Buffer::FileChunk::BUFFER_HEADER + size + data)
59
+ end
60
+ end
61
+
62
+ sub_test_case 'non configured buffer plugin instance' do
63
+ setup do
64
+ Fluent::Test.setup
65
+
66
+ @dir = File.expand_path('../../tmp/buffer_file_dir', __FILE__)
67
+ FileUtils.rm_rf @dir
68
+ FileUtils.mkdir_p @dir
69
+ end
70
+
71
+ test 'path should include * normally' do
72
+ d = FluentPluginFileBufferTest::DummyOutputPlugin.new
73
+ p = Fluent::Plugin::FileBuffer.new
74
+ p.owner = d
75
+ p.configure(config_element('buffer', '', {'path' => File.join(@dir, 'buffer.*.file')}))
76
+ assert_equal File.join(@dir, 'buffer.*.file'), p.path
77
+ end
78
+
79
+ data('default' => [nil, 'log'],
80
+ 'conf' => ['.buf', 'buf'])
81
+ test 'existing directory will be used with additional default file name' do |params|
82
+ conf, suffix = params
83
+ d = FluentPluginFileBufferTest::DummyOutputPlugin.new
84
+ p = Fluent::Plugin::FileBuffer.new
85
+ p.owner = d
86
+ c = {'path' => @dir}
87
+ c['path_suffix'] = conf if conf
88
+ p.configure(config_element('buffer', '', c))
89
+ assert_equal File.join(@dir, "buffer.*.#{suffix}"), p.path
90
+ end
91
+
92
+ data('default' => [nil, 'log'],
93
+ 'conf' => ['.buf', 'buf'])
94
+ test 'unexisting path without * handled as directory' do |params|
95
+ conf, suffix = params
96
+ d = FluentPluginFileBufferTest::DummyOutputPlugin.new
97
+ p = Fluent::Plugin::FileBuffer.new
98
+ p.owner = d
99
+ c = {'path' => File.join(@dir, 'buffer')}
100
+ c['path_suffix'] = conf if conf
101
+ p.configure(config_element('buffer', '', c))
102
+ assert_equal File.join(@dir, 'buffer', "buffer.*.#{suffix}"), p.path
103
+ end
104
+ end
105
+
106
+ sub_test_case 'buffer configurations and workers' do
107
+ setup do
108
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
109
+ FileUtils.rm_rf @bufdir
110
+ Fluent::Test.setup
111
+
112
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
113
+ @p = Fluent::Plugin::FileBuffer.new
114
+ @p.owner = @d
115
+ end
116
+
117
+ test 'raise error if configured path is of existing file' do
118
+ @bufpath = File.join(@bufdir, 'buf')
119
+ FileUtils.mkdir_p @bufdir
120
+ File.open(@bufpath, 'w'){|f| } # create and close the file
121
+ assert File.exist?(@bufpath)
122
+ assert File.file?(@bufpath)
123
+
124
+ buf_conf = config_element('buffer', '', {'path' => @bufpath})
125
+ assert_raise Fluent::ConfigError.new("Plugin 'file' does not support multi workers configuration (Fluent::Plugin::FileBuffer)") do
126
+ Fluent::SystemConfig.overwrite_system_config('workers' => 4) do
127
+ @d.configure(config_element('ROOT', '', {'@id' => 'dummy_output_with_buf'}, [buf_conf]))
128
+ end
129
+ end
130
+ end
131
+
132
+ test 'raise error if fluentd is configured to use file path pattern and multi workers' do
133
+ @bufpath = File.join(@bufdir, 'testbuf.*.log')
134
+ buf_conf = config_element('buffer', '', {'path' => @bufpath})
135
+ assert_raise Fluent::ConfigError.new("Plugin 'file' does not support multi workers configuration (Fluent::Plugin::FileBuffer)") do
136
+ Fluent::SystemConfig.overwrite_system_config('workers' => 4) do
137
+ @d.configure(config_element('ROOT', '', {'@id' => 'dummy_output_with_buf'}, [buf_conf]))
138
+ end
139
+ end
140
+ end
141
+
142
+ test 'enables multi worker configuration with unexisting directory path' do
143
+ assert_false File.exist?(@bufdir)
144
+ buf_conf = config_element('buffer', '', {'path' => @bufdir})
145
+ assert_nothing_raised do
146
+ Fluent::SystemConfig.overwrite_system_config('root_dir' => @bufdir, 'workers' => 4) do
147
+ @d.configure(config_element('ROOT', '', {}, [buf_conf]))
148
+ end
149
+ end
150
+ end
151
+
152
+ test 'enables multi worker configuration with existing directory path' do
153
+ FileUtils.mkdir_p @bufdir
154
+ buf_conf = config_element('buffer', '', {'path' => @bufdir})
155
+ assert_nothing_raised do
156
+ Fluent::SystemConfig.overwrite_system_config('root_dir' => @bufdir, 'workers' => 4) do
157
+ @d.configure(config_element('ROOT', '', {}, [buf_conf]))
158
+ end
159
+ end
160
+ end
161
+
162
+ test 'enables multi worker configuration with root dir' do
163
+ buf_conf = config_element('buffer', '')
164
+ assert_nothing_raised do
165
+ Fluent::SystemConfig.overwrite_system_config('root_dir' => @bufdir, 'workers' => 4) do
166
+ @d.configure(config_element('ROOT', '', {'@id' => 'dummy_output_with_buf'}, [buf_conf]))
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ sub_test_case 'buffer plugin configured only with path' do
173
+ setup do
174
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
175
+ @bufpath = File.join(@bufdir, 'testbuf.*.log')
176
+ FileUtils.rm_r @bufdir if File.exist?(@bufdir)
177
+
178
+ Fluent::Test.setup
179
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
180
+ @p = Fluent::Plugin::FileBuffer.new
181
+ @p.owner = @d
182
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
183
+ @p.start
184
+ end
185
+
186
+ teardown do
187
+ if @p
188
+ @p.stop unless @p.stopped?
189
+ @p.before_shutdown unless @p.before_shutdown?
190
+ @p.shutdown unless @p.shutdown?
191
+ @p.after_shutdown unless @p.after_shutdown?
192
+ @p.close unless @p.closed?
193
+ @p.terminate unless @p.terminated?
194
+ end
195
+ if @bufdir
196
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
197
+ next if ['.', '..'].include?(File.basename(path))
198
+ File.delete(path)
199
+ end
200
+ end
201
+ end
202
+
203
+ test 'this is persistent plugin' do
204
+ assert @p.persistent?
205
+ end
206
+
207
+ test '#start creates directory for buffer chunks' do
208
+ plugin = Fluent::Plugin::FileBuffer.new
209
+ plugin.owner = @d
210
+ rand_num = rand(0..100)
211
+ bufpath = File.join(File.expand_path("../../tmp/buffer_file_#{rand_num}", __FILE__), 'testbuf.*.log')
212
+ bufdir = File.dirname(bufpath)
213
+
214
+ FileUtils.rm_r bufdir if File.exist?(bufdir)
215
+ assert !File.exist?(bufdir)
216
+
217
+ plugin.configure(config_element('buffer', '', {'path' => bufpath}))
218
+ assert !File.exist?(bufdir)
219
+
220
+ plugin.start
221
+ assert File.exist?(bufdir)
222
+ assert{ File.stat(bufdir).mode.to_s(8).end_with?('755') }
223
+
224
+ plugin.stop; plugin.before_shutdown; plugin.shutdown; plugin.after_shutdown; plugin.close; plugin.terminate
225
+ FileUtils.rm_r bufdir
226
+ end
227
+
228
+ test '#start creates directory for buffer chunks with specified permission' do
229
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
230
+
231
+ plugin = Fluent::Plugin::FileBuffer.new
232
+ plugin.owner = @d
233
+ rand_num = rand(0..100)
234
+ bufpath = File.join(File.expand_path("../../tmp/buffer_file_#{rand_num}", __FILE__), 'testbuf.*.log')
235
+ bufdir = File.dirname(bufpath)
236
+
237
+ FileUtils.rm_r bufdir if File.exist?(bufdir)
238
+ assert !File.exist?(bufdir)
239
+
240
+ plugin.configure(config_element('buffer', '', {'path' => bufpath, 'dir_permission' => '0700'}))
241
+ assert !File.exist?(bufdir)
242
+
243
+ plugin.start
244
+ assert File.exist?(bufdir)
245
+ assert{ File.stat(bufdir).mode.to_s(8).end_with?('700') }
246
+
247
+ plugin.stop; plugin.before_shutdown; plugin.shutdown; plugin.after_shutdown; plugin.close; plugin.terminate
248
+ FileUtils.rm_r bufdir
249
+ end
250
+
251
+ test '#start creates directory for buffer chunks with specified permission via system config' do
252
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
253
+
254
+ sysconf = {'dir_permission' => '700'}
255
+ Fluent::SystemConfig.overwrite_system_config(sysconf) do
256
+ plugin = Fluent::Plugin::FileBuffer.new
257
+ plugin.owner = @d
258
+ rand_num = rand(0..100)
259
+ bufpath = File.join(File.expand_path("../../tmp/buffer_file_#{rand_num}", __FILE__), 'testbuf.*.log')
260
+ bufdir = File.dirname(bufpath)
261
+
262
+ FileUtils.rm_r bufdir if File.exist?(bufdir)
263
+ assert !File.exist?(bufdir)
264
+
265
+ plugin.configure(config_element('buffer', '', {'path' => bufpath}))
266
+ assert !File.exist?(bufdir)
267
+
268
+ plugin.start
269
+ assert File.exist?(bufdir)
270
+ assert{ File.stat(bufdir).mode.to_s(8).end_with?('700') }
271
+
272
+ plugin.stop; plugin.before_shutdown; plugin.shutdown; plugin.after_shutdown; plugin.close; plugin.terminate
273
+ FileUtils.rm_r bufdir
274
+ end
275
+ end
276
+
277
+ test '#generate_chunk generates blank file chunk on path from unique_id of metadata' do
278
+ m1 = metadata()
279
+ c1 = @p.generate_chunk(m1)
280
+ assert c1.is_a? Fluent::Plugin::Buffer::FileChunk
281
+ assert_equal m1, c1.metadata
282
+ assert c1.empty?
283
+ assert_equal :unstaged, c1.state
284
+ assert_equal Fluent::DEFAULT_FILE_PERMISSION, c1.permission
285
+ assert_equal @bufpath.gsub('.*.', ".b#{Fluent::UniqueId.hex(c1.unique_id)}."), c1.path
286
+ assert{ File.stat(c1.path).mode.to_s(8).end_with?('644') }
287
+
288
+ m2 = metadata(timekey: event_time('2016-04-17 11:15:00 -0700').to_i)
289
+ c2 = @p.generate_chunk(m2)
290
+ assert c2.is_a? Fluent::Plugin::Buffer::FileChunk
291
+ assert_equal m2, c2.metadata
292
+ assert c2.empty?
293
+ assert_equal :unstaged, c2.state
294
+ assert_equal Fluent::DEFAULT_FILE_PERMISSION, c2.permission
295
+ assert_equal @bufpath.gsub('.*.', ".b#{Fluent::UniqueId.hex(c2.unique_id)}."), c2.path
296
+ assert{ File.stat(c2.path).mode.to_s(8).end_with?('644') }
297
+
298
+ c1.purge
299
+ c2.purge
300
+ end
301
+
302
+ test '#generate_chunk generates blank file chunk with specified permission' do
303
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
304
+
305
+ plugin = Fluent::Plugin::FileBuffer.new
306
+ plugin.owner = @d
307
+ rand_num = rand(0..100)
308
+ bufpath = File.join(File.expand_path("../../tmp/buffer_file_#{rand_num}", __FILE__), 'testbuf.*.log')
309
+ bufdir = File.dirname(bufpath)
310
+
311
+ FileUtils.rm_r bufdir if File.exist?(bufdir)
312
+ assert !File.exist?(bufdir)
313
+
314
+ plugin.configure(config_element('buffer', '', {'path' => bufpath, 'file_permission' => '0600'}))
315
+ assert !File.exist?(bufdir)
316
+ plugin.start
317
+
318
+ m = metadata()
319
+ c = plugin.generate_chunk(m)
320
+ assert c.is_a? Fluent::Plugin::Buffer::FileChunk
321
+ assert_equal m, c.metadata
322
+ assert c.empty?
323
+ assert_equal :unstaged, c.state
324
+ assert_equal 0600, c.permission
325
+ assert_equal bufpath.gsub('.*.', ".b#{Fluent::UniqueId.hex(c.unique_id)}."), c.path
326
+ assert{ File.stat(c.path).mode.to_s(8).end_with?('600') }
327
+
328
+ c.purge
329
+
330
+ plugin.stop; plugin.before_shutdown; plugin.shutdown; plugin.after_shutdown; plugin.close; plugin.terminate
331
+ FileUtils.rm_r bufdir
332
+ end
333
+
334
+ test '#generate_chunk generates blank file chunk with specified permission with system_config' do
335
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
336
+
337
+ begin
338
+ plugin = Fluent::Plugin::FileBuffer.new
339
+ plugin.owner = @d
340
+ rand_num = rand(0..100)
341
+ bufpath = File.join(File.expand_path("../../tmp/buffer_file_#{rand_num}", __FILE__), 'testbuf.*.log')
342
+ bufdir = File.dirname(bufpath)
343
+
344
+ FileUtils.rm_r bufdir if File.exist?(bufdir)
345
+ assert !File.exist?(bufdir)
346
+
347
+ plugin.configure(config_element('buffer', '', { 'path' => bufpath }))
348
+
349
+ assert !File.exist?(bufdir)
350
+ plugin.start
351
+
352
+ m = metadata()
353
+ c = nil
354
+ Fluent::SystemConfig.overwrite_system_config("file_permission" => "700") do
355
+ c = plugin.generate_chunk(m)
356
+ end
357
+
358
+ assert c.is_a? Fluent::Plugin::Buffer::FileChunk
359
+ assert_equal m, c.metadata
360
+ assert c.empty?
361
+ assert_equal :unstaged, c.state
362
+ assert_equal 0700, c.permission
363
+ assert_equal bufpath.gsub('.*.', ".b#{Fluent::UniqueId.hex(c.unique_id)}."), c.path
364
+ assert{ File.stat(c.path).mode.to_s(8).end_with?('700') }
365
+
366
+ c.purge
367
+
368
+ plugin.stop; plugin.before_shutdown; plugin.shutdown; plugin.after_shutdown; plugin.close; plugin.terminate
369
+ ensure
370
+ FileUtils.rm_r bufdir
371
+ end
372
+ end
373
+ end
374
+
375
+ sub_test_case 'configured with system root directory and plugin @id' do
376
+ setup do
377
+ @root_dir = File.expand_path('../../tmp/buffer_file_root', __FILE__)
378
+ FileUtils.rm_rf @root_dir
379
+
380
+ Fluent::Test.setup
381
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
382
+ @p = Fluent::Plugin::FileBuffer.new
383
+ @p.owner = @d
384
+ end
385
+
386
+ teardown do
387
+ if @p
388
+ @p.stop unless @p.stopped?
389
+ @p.before_shutdown unless @p.before_shutdown?
390
+ @p.shutdown unless @p.shutdown?
391
+ @p.after_shutdown unless @p.after_shutdown?
392
+ @p.close unless @p.closed?
393
+ @p.terminate unless @p.terminated?
394
+ end
395
+ end
396
+
397
+ data('default' => [nil, 'log'],
398
+ 'conf' => ['.buf', 'buf'])
399
+ test '#start creates directory for buffer chunks' do |params|
400
+ conf, suffix = params
401
+ c = {}
402
+ c['path_suffix'] = conf if conf
403
+ Fluent::SystemConfig.overwrite_system_config('root_dir' => @root_dir) do
404
+ @d.configure(config_element('ROOT', '', {'@id' => 'dummy_output_with_buf'}))
405
+ @p.configure(config_element('buffer', '', c))
406
+ end
407
+
408
+ expected_buffer_path = File.join(@root_dir, 'worker0', 'dummy_output_with_buf', 'buffer', "buffer.*.#{suffix}")
409
+ expected_buffer_dir = File.dirname(expected_buffer_path)
410
+ assert_equal expected_buffer_path, @p.path
411
+ assert_false Dir.exist?(expected_buffer_dir)
412
+
413
+ @p.start
414
+
415
+ assert Dir.exist?(expected_buffer_dir)
416
+ end
417
+ end
418
+
419
+ sub_test_case 'there are no existing file chunks' do
420
+ setup do
421
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
422
+ @bufpath = File.join(@bufdir, 'testbuf.*.log')
423
+ FileUtils.rm_r @bufdir if File.exist?(@bufdir)
424
+
425
+ Fluent::Test.setup
426
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
427
+ @p = Fluent::Plugin::FileBuffer.new
428
+ @p.owner = @d
429
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
430
+ @p.start
431
+ end
432
+ teardown do
433
+ if @p
434
+ @p.stop unless @p.stopped?
435
+ @p.before_shutdown unless @p.before_shutdown?
436
+ @p.shutdown unless @p.shutdown?
437
+ @p.after_shutdown unless @p.after_shutdown?
438
+ @p.close unless @p.closed?
439
+ @p.terminate unless @p.terminated?
440
+ end
441
+ if @bufdir
442
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
443
+ next if ['.', '..'].include?(File.basename(path))
444
+ File.delete(path)
445
+ end
446
+ end
447
+ end
448
+
449
+ test '#resume returns empty buffer state' do
450
+ ary = @p.resume
451
+ assert_equal({}, ary[0])
452
+ assert_equal([], ary[1])
453
+ end
454
+ end
455
+
456
+ sub_test_case 'there are some existing file chunks' do
457
+ setup do
458
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
459
+ FileUtils.mkdir_p @bufdir unless File.exist?(@bufdir)
460
+
461
+ @c1id = Fluent::UniqueId.generate
462
+ p1 = File.join(@bufdir, "etest.q#{Fluent::UniqueId.hex(@c1id)}.log")
463
+ File.open(p1, 'wb') do |f|
464
+ f.write ["t1.test", event_time('2016-04-17 13:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
465
+ f.write ["t2.test", event_time('2016-04-17 13:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
466
+ f.write ["t3.test", event_time('2016-04-17 13:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
467
+ f.write ["t4.test", event_time('2016-04-17 13:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
468
+ end
469
+ write_metadata(
470
+ p1 + '.meta', @c1id, metadata(timekey: event_time('2016-04-17 13:58:00 -0700').to_i),
471
+ 4, event_time('2016-04-17 13:58:00 -0700').to_i, event_time('2016-04-17 13:58:22 -0700').to_i
472
+ )
473
+
474
+ @c2id = Fluent::UniqueId.generate
475
+ p2 = File.join(@bufdir, "etest.q#{Fluent::UniqueId.hex(@c2id)}.log")
476
+ File.open(p2, 'wb') do |f|
477
+ f.write ["t1.test", event_time('2016-04-17 13:59:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
478
+ f.write ["t2.test", event_time('2016-04-17 13:59:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
479
+ f.write ["t3.test", event_time('2016-04-17 13:59:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
480
+ end
481
+ write_metadata(
482
+ p2 + '.meta', @c2id, metadata(timekey: event_time('2016-04-17 13:59:00 -0700').to_i),
483
+ 3, event_time('2016-04-17 13:59:00 -0700').to_i, event_time('2016-04-17 13:59:23 -0700').to_i
484
+ )
485
+
486
+ @c3id = Fluent::UniqueId.generate
487
+ p3 = File.join(@bufdir, "etest.b#{Fluent::UniqueId.hex(@c3id)}.log")
488
+ File.open(p3, 'wb') do |f|
489
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
490
+ f.write ["t2.test", event_time('2016-04-17 14:00:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
491
+ f.write ["t3.test", event_time('2016-04-17 14:00:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
492
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay"}].to_json + "\n"
493
+ end
494
+ write_metadata(
495
+ p3 + '.meta', @c3id, metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i),
496
+ 4, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i
497
+ )
498
+
499
+ @c4id = Fluent::UniqueId.generate
500
+ p4 = File.join(@bufdir, "etest.b#{Fluent::UniqueId.hex(@c4id)}.log")
501
+ File.open(p4, 'wb') do |f|
502
+ f.write ["t1.test", event_time('2016-04-17 14:01:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
503
+ f.write ["t2.test", event_time('2016-04-17 14:01:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
504
+ f.write ["t3.test", event_time('2016-04-17 14:01:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
505
+ end
506
+ write_metadata(
507
+ p4 + '.meta', @c4id, metadata(timekey: event_time('2016-04-17 14:01:00 -0700').to_i),
508
+ 3, event_time('2016-04-17 14:01:00 -0700').to_i, event_time('2016-04-17 14:01:25 -0700').to_i
509
+ )
510
+
511
+ @bufpath = File.join(@bufdir, 'etest.*.log')
512
+
513
+ Fluent::Test.setup
514
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
515
+ @p = Fluent::Plugin::FileBuffer.new
516
+ @p.owner = @d
517
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
518
+ @p.start
519
+ end
520
+
521
+ teardown do
522
+ if @p
523
+ @p.stop unless @p.stopped?
524
+ @p.before_shutdown unless @p.before_shutdown?
525
+ @p.shutdown unless @p.shutdown?
526
+ @p.after_shutdown unless @p.after_shutdown?
527
+ @p.close unless @p.closed?
528
+ @p.terminate unless @p.terminated?
529
+ end
530
+ if @bufdir
531
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
532
+ next if ['.', '..'].include?(File.basename(path))
533
+ File.delete(path)
534
+ end
535
+ end
536
+ end
537
+
538
+ test '#resume returns staged/queued chunks with metadata' do
539
+ assert_equal 2, @p.stage.size
540
+ assert_equal 2, @p.queue.size
541
+
542
+ stage = @p.stage
543
+
544
+ m3 = metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i)
545
+ assert_equal @c3id, stage[m3].unique_id
546
+ assert_equal 4, stage[m3].size
547
+ assert_equal :staged, stage[m3].state
548
+
549
+ m4 = metadata(timekey: event_time('2016-04-17 14:01:00 -0700').to_i)
550
+ assert_equal @c4id, stage[m4].unique_id
551
+ assert_equal 3, stage[m4].size
552
+ assert_equal :staged, stage[m4].state
553
+ end
554
+
555
+ test '#resume returns queued chunks ordered by last modified time (FIFO)' do
556
+ assert_equal 2, @p.stage.size
557
+ assert_equal 2, @p.queue.size
558
+
559
+ queue = @p.queue
560
+
561
+ assert{ queue[0].modified_at < queue[1].modified_at }
562
+
563
+ assert_equal @c1id, queue[0].unique_id
564
+ assert_equal :queued, queue[0].state
565
+ assert_equal event_time('2016-04-17 13:58:00 -0700').to_i, queue[0].metadata.timekey
566
+ assert_nil queue[0].metadata.tag
567
+ assert_nil queue[0].metadata.variables
568
+ assert_equal Time.parse('2016-04-17 13:58:00 -0700').localtime, queue[0].created_at
569
+ assert_equal Time.parse('2016-04-17 13:58:22 -0700').localtime, queue[0].modified_at
570
+ assert_equal 4, queue[0].size
571
+
572
+ assert_equal @c2id, queue[1].unique_id
573
+ assert_equal :queued, queue[1].state
574
+ assert_equal event_time('2016-04-17 13:59:00 -0700').to_i, queue[1].metadata.timekey
575
+ assert_nil queue[1].metadata.tag
576
+ assert_nil queue[1].metadata.variables
577
+ assert_equal Time.parse('2016-04-17 13:59:00 -0700').localtime, queue[1].created_at
578
+ assert_equal Time.parse('2016-04-17 13:59:23 -0700').localtime, queue[1].modified_at
579
+ assert_equal 3, queue[1].size
580
+ end
581
+ end
582
+
583
+ sub_test_case 'there are some existing file chunks with placeholders path' do
584
+ setup do
585
+ @bufdir = File.expand_path('../../tmp/buffer_${test}_file', __FILE__)
586
+ FileUtils.rm_rf(@bufdir)
587
+ FileUtils.mkdir_p(@bufdir)
588
+
589
+ @c1id = Fluent::UniqueId.generate
590
+ p1 = File.join(@bufdir, "etest.q#{Fluent::UniqueId.hex(@c1id)}.log")
591
+ File.open(p1, 'wb') do |f|
592
+ f.write ["t1.test", event_time('2016-04-17 13:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
593
+ end
594
+ write_metadata(
595
+ p1 + '.meta', @c1id, metadata(timekey: event_time('2016-04-17 13:58:00 -0700').to_i),
596
+ 1, event_time('2016-04-17 13:58:00 -0700').to_i, event_time('2016-04-17 13:58:22 -0700').to_i
597
+ )
598
+
599
+ @c2id = Fluent::UniqueId.generate
600
+ p2 = File.join(@bufdir, "etest.b#{Fluent::UniqueId.hex(@c2id)}.log")
601
+ File.open(p2, 'wb') do |f|
602
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
603
+ end
604
+ write_metadata(
605
+ p2 + '.meta', @c2id, metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i),
606
+ 1, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i
607
+ )
608
+
609
+ @bufpath = File.join(@bufdir, 'etest.*.log')
610
+
611
+ Fluent::Test.setup
612
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
613
+ @p = Fluent::Plugin::FileBuffer.new
614
+ @p.owner = @d
615
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
616
+ @p.start
617
+ end
618
+
619
+ teardown do
620
+ if @p
621
+ @p.stop unless @p.stopped?
622
+ @p.before_shutdown unless @p.before_shutdown?
623
+ @p.shutdown unless @p.shutdown?
624
+ @p.after_shutdown unless @p.after_shutdown?
625
+ @p.close unless @p.closed?
626
+ @p.terminate unless @p.terminated?
627
+ end
628
+ FileUtils.rm_rf(@bufdir)
629
+ end
630
+
631
+ test '#resume returns staged/queued chunks with metadata' do
632
+ assert_equal 1, @p.stage.size
633
+ assert_equal 1, @p.queue.size
634
+ end
635
+ end
636
+
637
+ sub_test_case 'there are some existing file chunks, both in specified path and per-worker directory under specified path, configured as multi workers' do
638
+ setup do
639
+ @bufdir = File.expand_path('../../tmp/buffer_file/path', __FILE__)
640
+ @worker0_dir = File.join(@bufdir, "worker0")
641
+ @worker1_dir = File.join(@bufdir, "worker1")
642
+ FileUtils.rm_rf @bufdir
643
+ FileUtils.mkdir_p @worker0_dir
644
+ FileUtils.mkdir_p @worker1_dir
645
+
646
+ @bufdir_chunk_1 = Fluent::UniqueId.generate
647
+ bc1 = File.join(@bufdir, "buffer.q#{Fluent::UniqueId.hex(@bufdir_chunk_1)}.log")
648
+ File.open(bc1, 'wb') do |f|
649
+ f.write ["t1.test", event_time('2016-04-17 13:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
650
+ f.write ["t2.test", event_time('2016-04-17 13:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
651
+ f.write ["t3.test", event_time('2016-04-17 13:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
652
+ f.write ["t4.test", event_time('2016-04-17 13:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
653
+ end
654
+ write_metadata(
655
+ bc1 + '.meta', @bufdir_chunk_1, metadata(timekey: event_time('2016-04-17 13:58:00 -0700').to_i),
656
+ 4, event_time('2016-04-17 13:58:00 -0700').to_i, event_time('2016-04-17 13:58:22 -0700').to_i
657
+ )
658
+
659
+ @bufdir_chunk_2 = Fluent::UniqueId.generate
660
+ bc2 = File.join(@bufdir, "buffer.q#{Fluent::UniqueId.hex(@bufdir_chunk_2)}.log")
661
+ File.open(bc2, 'wb') do |f|
662
+ f.write ["t1.test", event_time('2016-04-17 13:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
663
+ f.write ["t2.test", event_time('2016-04-17 13:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
664
+ f.write ["t3.test", event_time('2016-04-17 13:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
665
+ f.write ["t4.test", event_time('2016-04-17 13:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
666
+ end
667
+ write_metadata(
668
+ bc2 + '.meta', @bufdir_chunk_2, metadata(timekey: event_time('2016-04-17 13:58:00 -0700').to_i),
669
+ 4, event_time('2016-04-17 13:58:00 -0700').to_i, event_time('2016-04-17 13:58:22 -0700').to_i
670
+ )
671
+
672
+ @worker_dir_chunk_1 = Fluent::UniqueId.generate
673
+ wc0_1 = File.join(@worker0_dir, "buffer.q#{Fluent::UniqueId.hex(@worker_dir_chunk_1)}.log")
674
+ wc1_1 = File.join(@worker1_dir, "buffer.q#{Fluent::UniqueId.hex(@worker_dir_chunk_1)}.log")
675
+ [wc0_1, wc1_1].each do |chunk_path|
676
+ File.open(chunk_path, 'wb') do |f|
677
+ f.write ["t1.test", event_time('2016-04-17 13:59:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
678
+ f.write ["t2.test", event_time('2016-04-17 13:59:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
679
+ f.write ["t3.test", event_time('2016-04-17 13:59:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
680
+ end
681
+ write_metadata(
682
+ chunk_path + '.meta', @worker_dir_chunk_1, metadata(timekey: event_time('2016-04-17 13:59:00 -0700').to_i),
683
+ 3, event_time('2016-04-17 13:59:00 -0700').to_i, event_time('2016-04-17 13:59:23 -0700').to_i
684
+ )
685
+ end
686
+
687
+ @worker_dir_chunk_2 = Fluent::UniqueId.generate
688
+ wc0_2 = File.join(@worker0_dir, "buffer.b#{Fluent::UniqueId.hex(@worker_dir_chunk_2)}.log")
689
+ wc1_2 = File.join(@worker1_dir, "buffer.b#{Fluent::UniqueId.hex(@worker_dir_chunk_2)}.log")
690
+ [wc0_2, wc1_2].each do |chunk_path|
691
+ File.open(chunk_path, 'wb') do |f|
692
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
693
+ f.write ["t2.test", event_time('2016-04-17 14:00:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
694
+ f.write ["t3.test", event_time('2016-04-17 14:00:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
695
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay"}].to_json + "\n"
696
+ end
697
+ write_metadata(
698
+ chunk_path + '.meta', @worker_dir_chunk_2, metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i),
699
+ 4, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i
700
+ )
701
+ end
702
+
703
+ @worker_dir_chunk_3 = Fluent::UniqueId.generate
704
+ wc0_3 = File.join(@worker0_dir, "buffer.b#{Fluent::UniqueId.hex(@worker_dir_chunk_3)}.log")
705
+ wc1_3 = File.join(@worker1_dir, "buffer.b#{Fluent::UniqueId.hex(@worker_dir_chunk_3)}.log")
706
+ [wc0_3, wc1_3].each do |chunk_path|
707
+ File.open(chunk_path, 'wb') do |f|
708
+ f.write ["t1.test", event_time('2016-04-17 14:01:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
709
+ f.write ["t2.test", event_time('2016-04-17 14:01:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
710
+ f.write ["t3.test", event_time('2016-04-17 14:01:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
711
+ end
712
+ write_metadata(
713
+ chunk_path + '.meta', @worker_dir_chunk_3, metadata(timekey: event_time('2016-04-17 14:01:00 -0700').to_i),
714
+ 3, event_time('2016-04-17 14:01:00 -0700').to_i, event_time('2016-04-17 14:01:25 -0700').to_i
715
+ )
716
+ end
717
+
718
+ Fluent::Test.setup
719
+ end
720
+
721
+ teardown do
722
+ if @p
723
+ @p.stop unless @p.stopped?
724
+ @p.before_shutdown unless @p.before_shutdown?
725
+ @p.shutdown unless @p.shutdown?
726
+ @p.after_shutdown unless @p.after_shutdown?
727
+ @p.close unless @p.closed?
728
+ @p.terminate unless @p.terminated?
729
+ end
730
+ end
731
+
732
+ test 'worker(id=0) #resume returns staged/queued chunks with metadata, not only in worker dir, including the directory specified by path' do
733
+ ENV['SERVERENGINE_WORKER_ID'] = '0'
734
+
735
+ buf_conf = config_element('buffer', '', {'path' => @bufdir})
736
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
737
+ with_worker_config(workers: 2, worker_id: 0) do
738
+ @d.configure(config_element('output', '', {}, [buf_conf]))
739
+ end
740
+
741
+ @d.start
742
+ @p = @d.buffer
743
+
744
+ assert_equal 2, @p.stage.size
745
+ assert_equal 3, @p.queue.size
746
+
747
+ stage = @p.stage
748
+
749
+ m1 = metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i)
750
+ assert_equal @worker_dir_chunk_2, stage[m1].unique_id
751
+ assert_equal 4, stage[m1].size
752
+ assert_equal :staged, stage[m1].state
753
+
754
+ m2 = metadata(timekey: event_time('2016-04-17 14:01:00 -0700').to_i)
755
+ assert_equal @worker_dir_chunk_3, stage[m2].unique_id
756
+ assert_equal 3, stage[m2].size
757
+ assert_equal :staged, stage[m2].state
758
+
759
+ queue = @p.queue
760
+
761
+ assert_equal [@bufdir_chunk_1, @bufdir_chunk_2, @worker_dir_chunk_1].sort, queue.map(&:unique_id).sort
762
+ assert_equal [3, 4, 4], queue.map(&:size).sort
763
+ assert_equal [:queued, :queued, :queued], queue.map(&:state)
764
+ end
765
+
766
+ test 'worker(id=1) #resume returns staged/queued chunks with metadata, only in worker dir' do
767
+ buf_conf = config_element('buffer', '', {'path' => @bufdir})
768
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
769
+ with_worker_config(workers: 2, worker_id: 1) do
770
+ @d.configure(config_element('output', '', {}, [buf_conf]))
771
+ end
772
+
773
+ @d.start
774
+ @p = @d.buffer
775
+
776
+ assert_equal 2, @p.stage.size
777
+ assert_equal 1, @p.queue.size
778
+
779
+ stage = @p.stage
780
+
781
+ m1 = metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i)
782
+ assert_equal @worker_dir_chunk_2, stage[m1].unique_id
783
+ assert_equal 4, stage[m1].size
784
+ assert_equal :staged, stage[m1].state
785
+
786
+ m2 = metadata(timekey: event_time('2016-04-17 14:01:00 -0700').to_i)
787
+ assert_equal @worker_dir_chunk_3, stage[m2].unique_id
788
+ assert_equal 3, stage[m2].size
789
+ assert_equal :staged, stage[m2].state
790
+
791
+ queue = @p.queue
792
+
793
+ assert_equal @worker_dir_chunk_1, queue[0].unique_id
794
+ assert_equal 3, queue[0].size
795
+ assert_equal :queued, queue[0].state
796
+ end
797
+ end
798
+
799
+ sub_test_case 'there are some existing file chunks with old format metadta' do
800
+ setup do
801
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
802
+ FileUtils.mkdir_p @bufdir unless File.exist?(@bufdir)
803
+
804
+ @c1id = Fluent::UniqueId.generate
805
+ p1 = File.join(@bufdir, "etest.q#{Fluent::UniqueId.hex(@c1id)}.log")
806
+ File.open(p1, 'wb') do |f|
807
+ f.write ["t1.test", event_time('2016-04-17 13:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
808
+ f.write ["t2.test", event_time('2016-04-17 13:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
809
+ f.write ["t3.test", event_time('2016-04-17 13:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
810
+ f.write ["t4.test", event_time('2016-04-17 13:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
811
+ end
812
+ write_metadata_old(
813
+ p1 + '.meta', @c1id, metadata(timekey: event_time('2016-04-17 13:58:00 -0700').to_i),
814
+ 4, event_time('2016-04-17 13:58:00 -0700').to_i, event_time('2016-04-17 13:58:22 -0700').to_i
815
+ )
816
+
817
+ @c2id = Fluent::UniqueId.generate
818
+ p2 = File.join(@bufdir, "etest.q#{Fluent::UniqueId.hex(@c2id)}.log")
819
+ File.open(p2, 'wb') do |f|
820
+ f.write ["t1.test", event_time('2016-04-17 13:59:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
821
+ f.write ["t2.test", event_time('2016-04-17 13:59:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
822
+ f.write ["t3.test", event_time('2016-04-17 13:59:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
823
+ end
824
+ write_metadata_old(
825
+ p2 + '.meta', @c2id, metadata(timekey: event_time('2016-04-17 13:59:00 -0700').to_i),
826
+ 3, event_time('2016-04-17 13:59:00 -0700').to_i, event_time('2016-04-17 13:59:23 -0700').to_i
827
+ )
828
+
829
+ @c3id = Fluent::UniqueId.generate
830
+ p3 = File.join(@bufdir, "etest.b#{Fluent::UniqueId.hex(@c3id)}.log")
831
+ File.open(p3, 'wb') do |f|
832
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
833
+ f.write ["t2.test", event_time('2016-04-17 14:00:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
834
+ f.write ["t3.test", event_time('2016-04-17 14:00:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
835
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay"}].to_json + "\n"
836
+ end
837
+ write_metadata_old(
838
+ p3 + '.meta', @c3id, metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i),
839
+ 4, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i
840
+ )
841
+
842
+ @c4id = Fluent::UniqueId.generate
843
+ p4 = File.join(@bufdir, "etest.b#{Fluent::UniqueId.hex(@c4id)}.log")
844
+ File.open(p4, 'wb') do |f|
845
+ f.write ["t1.test", event_time('2016-04-17 14:01:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
846
+ f.write ["t2.test", event_time('2016-04-17 14:01:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
847
+ f.write ["t3.test", event_time('2016-04-17 14:01:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
848
+ end
849
+ write_metadata_old(
850
+ p4 + '.meta', @c4id, metadata(timekey: event_time('2016-04-17 14:01:00 -0700').to_i),
851
+ 3, event_time('2016-04-17 14:01:00 -0700').to_i, event_time('2016-04-17 14:01:25 -0700').to_i
852
+ )
853
+
854
+ @bufpath = File.join(@bufdir, 'etest.*.log')
855
+
856
+ Fluent::Test.setup
857
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
858
+ @p = Fluent::Plugin::FileBuffer.new
859
+ @p.owner = @d
860
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
861
+ @p.start
862
+ end
863
+
864
+ teardown do
865
+ if @p
866
+ @p.stop unless @p.stopped?
867
+ @p.before_shutdown unless @p.before_shutdown?
868
+ @p.shutdown unless @p.shutdown?
869
+ @p.after_shutdown unless @p.after_shutdown?
870
+ @p.close unless @p.closed?
871
+ @p.terminate unless @p.terminated?
872
+ end
873
+ if @bufdir
874
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
875
+ next if ['.', '..'].include?(File.basename(path))
876
+ File.delete(path)
877
+ end
878
+ end
879
+ end
880
+
881
+ test '#resume returns staged/queued chunks with metadata' do
882
+ assert_equal 2, @p.stage.size
883
+ assert_equal 2, @p.queue.size
884
+
885
+ stage = @p.stage
886
+
887
+ m3 = metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i)
888
+ assert_equal @c3id, stage[m3].unique_id
889
+ assert_equal 4, stage[m3].size
890
+ assert_equal :staged, stage[m3].state
891
+
892
+ m4 = metadata(timekey: event_time('2016-04-17 14:01:00 -0700').to_i)
893
+ assert_equal @c4id, stage[m4].unique_id
894
+ assert_equal 3, stage[m4].size
895
+ assert_equal :staged, stage[m4].state
896
+ end
897
+ end
898
+
899
+ sub_test_case 'there are some existing file chunks with old format metadata file' do
900
+ setup do
901
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
902
+
903
+ @c1id = Fluent::UniqueId.generate
904
+ p1 = File.join(@bufdir, "etest.201604171358.q#{Fluent::UniqueId.hex(@c1id)}.log")
905
+ File.open(p1, 'wb') do |f|
906
+ f.write ["t1.test", event_time('2016-04-17 13:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
907
+ f.write ["t2.test", event_time('2016-04-17 13:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
908
+ f.write ["t3.test", event_time('2016-04-17 13:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
909
+ f.write ["t4.test", event_time('2016-04-17 13:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
910
+ end
911
+ FileUtils.touch(p1, mtime: Time.parse('2016-04-17 13:58:28 -0700'))
912
+
913
+ @c2id = Fluent::UniqueId.generate
914
+ p2 = File.join(@bufdir, "etest.201604171359.q#{Fluent::UniqueId.hex(@c2id)}.log")
915
+ File.open(p2, 'wb') do |f|
916
+ f.write ["t1.test", event_time('2016-04-17 13:59:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
917
+ f.write ["t2.test", event_time('2016-04-17 13:59:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
918
+ f.write ["t3.test", event_time('2016-04-17 13:59:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
919
+ end
920
+ FileUtils.touch(p2, mtime: Time.parse('2016-04-17 13:59:30 -0700'))
921
+
922
+ @c3id = Fluent::UniqueId.generate
923
+ p3 = File.join(@bufdir, "etest.201604171400.b#{Fluent::UniqueId.hex(@c3id)}.log")
924
+ File.open(p3, 'wb') do |f|
925
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
926
+ f.write ["t2.test", event_time('2016-04-17 14:00:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
927
+ f.write ["t3.test", event_time('2016-04-17 14:00:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
928
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay"}].to_json + "\n"
929
+ end
930
+ FileUtils.touch(p3, mtime: Time.parse('2016-04-17 14:00:29 -0700'))
931
+
932
+ @c4id = Fluent::UniqueId.generate
933
+ p4 = File.join(@bufdir, "etest.201604171401.b#{Fluent::UniqueId.hex(@c4id)}.log")
934
+ File.open(p4, 'wb') do |f|
935
+ f.write ["t1.test", event_time('2016-04-17 14:01:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
936
+ f.write ["t2.test", event_time('2016-04-17 14:01:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
937
+ f.write ["t3.test", event_time('2016-04-17 14:01:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
938
+ end
939
+ FileUtils.touch(p4, mtime: Time.parse('2016-04-17 14:01:22 -0700'))
940
+
941
+ @bufpath = File.join(@bufdir, 'etest.*.log')
942
+
943
+ Fluent::Test.setup
944
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
945
+ @p = Fluent::Plugin::FileBuffer.new
946
+ @p.owner = @d
947
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
948
+ @p.start
949
+ end
950
+
951
+ teardown do
952
+ if @p
953
+ @p.stop unless @p.stopped?
954
+ @p.before_shutdown unless @p.before_shutdown?
955
+ @p.shutdown unless @p.shutdown?
956
+ @p.after_shutdown unless @p.after_shutdown?
957
+ @p.close unless @p.closed?
958
+ @p.terminate unless @p.terminated?
959
+ end
960
+ if @bufdir
961
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
962
+ next if ['.', '..'].include?(File.basename(path))
963
+ File.delete(path)
964
+ end
965
+ end
966
+ end
967
+
968
+ test '#resume returns queued chunks for files without metadata' do
969
+ assert_equal 0, @p.stage.size
970
+ assert_equal 4, @p.queue.size
971
+
972
+ queue = @p.queue
973
+
974
+ m = metadata()
975
+
976
+ assert_equal @c1id, queue[0].unique_id
977
+ assert_equal m, queue[0].metadata
978
+ assert_equal 0, queue[0].size
979
+ assert_equal :queued, queue[0].state
980
+ assert_equal Time.parse('2016-04-17 13:58:28 -0700'), queue[0].modified_at
981
+
982
+ assert_equal @c2id, queue[1].unique_id
983
+ assert_equal m, queue[1].metadata
984
+ assert_equal 0, queue[1].size
985
+ assert_equal :queued, queue[1].state
986
+ assert_equal Time.parse('2016-04-17 13:59:30 -0700'), queue[1].modified_at
987
+
988
+ assert_equal @c3id, queue[2].unique_id
989
+ assert_equal m, queue[2].metadata
990
+ assert_equal 0, queue[2].size
991
+ assert_equal :queued, queue[2].state
992
+ assert_equal Time.parse('2016-04-17 14:00:29 -0700'), queue[2].modified_at
993
+
994
+ assert_equal @c4id, queue[3].unique_id
995
+ assert_equal m, queue[3].metadata
996
+ assert_equal 0, queue[3].size
997
+ assert_equal :queued, queue[3].state
998
+ assert_equal Time.parse('2016-04-17 14:01:22 -0700'), queue[3].modified_at
999
+ end
1000
+ end
1001
+
1002
+ sub_test_case 'there are the same timekey metadata in stage' do
1003
+ setup do
1004
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
1005
+ @bufpath = File.join(@bufdir, 'testbuf.*.log')
1006
+ FileUtils.rm_r(@bufdir) if File.exist?(@bufdir)
1007
+ FileUtils.mkdir_p(@bufdir)
1008
+
1009
+ m = metadata(timekey: event_time('2016-04-17 13:58:00 -0700').to_i)
1010
+
1011
+ c1id = Fluent::UniqueId.generate
1012
+ p1 = File.join(@bufdir, "testbuf.b#{Fluent::UniqueId.hex(c1id)}.log")
1013
+ File.open(p1, 'wb') do |f|
1014
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay1"}].to_json + "\n"
1015
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay2"}].to_json + "\n"
1016
+ end
1017
+ write_metadata(p1 + '.meta', c1id, m, 2, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i)
1018
+
1019
+ c2id = Fluent::UniqueId.generate
1020
+ p2 = File.join(@bufdir, "testbuf.b#{Fluent::UniqueId.hex(c2id)}.log")
1021
+ File.open(p2, 'wb') do |f|
1022
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay3"}].to_json + "\n"
1023
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay4"}].to_json + "\n"
1024
+ end
1025
+ m2 = m.dup_next
1026
+ write_metadata(p2 + '.meta', c2id, m2, 2, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i)
1027
+
1028
+ c3id = Fluent::UniqueId.generate
1029
+ p3 = File.join(@bufdir, "testbuf.b#{Fluent::UniqueId.hex(c3id)}.log")
1030
+ File.open(p3, 'wb') do |f|
1031
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay5"}].to_json + "\n"
1032
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay6"}].to_json + "\n"
1033
+ end
1034
+ m3 = m2.dup_next
1035
+ write_metadata(p3 + '.meta', c3id, m3, 2, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i)
1036
+
1037
+ c4id = Fluent::UniqueId.generate
1038
+ p4 = File.join(@bufdir, "testbuf.b#{Fluent::UniqueId.hex(c4id)}.log")
1039
+ File.open(p4, 'wb') do |f|
1040
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay5"}].to_json + "\n"
1041
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay6"}].to_json + "\n"
1042
+ end
1043
+ write_metadata(p4 + '.meta', c4id, m3, 2, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i)
1044
+
1045
+ Fluent::Test.setup
1046
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
1047
+ @p = Fluent::Plugin::FileBuffer.new
1048
+ @p.owner = @d
1049
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
1050
+ @p.start
1051
+ end
1052
+ teardown do
1053
+ if @p
1054
+ @p.stop unless @p.stopped?
1055
+ @p.before_shutdown unless @p.before_shutdown?
1056
+ @p.shutdown unless @p.shutdown?
1057
+ @p.after_shutdown unless @p.after_shutdown?
1058
+ @p.close unless @p.closed?
1059
+ @p.terminate unless @p.terminated?
1060
+ end
1061
+
1062
+ if @bufdir
1063
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
1064
+ next if ['.', '..'].include?(File.basename(path))
1065
+ # Windows does not permit to delete files which are used in another process.
1066
+ # Just ignore for removing failure.
1067
+ File.delete(path) rescue nil
1068
+ end
1069
+ end
1070
+ end
1071
+
1072
+ test '#resume returns each chunks' do
1073
+ s, e = @p.resume
1074
+ assert_equal 3, s.size
1075
+ assert_equal [0, 1, 2], s.keys.map(&:seq).sort
1076
+ assert_equal 1, e.size
1077
+ assert_equal [0], e.map { |e| e.metadata.seq }
1078
+ end
1079
+ end
1080
+
1081
+ sub_test_case 'there are some non-buffer chunk files, with a path without buffer chunk ids' do
1082
+ setup do
1083
+ @bufdir = File.expand_path('../../tmp/buffer_file', __FILE__)
1084
+
1085
+ FileUtils.rm_rf @bufdir
1086
+ FileUtils.mkdir_p @bufdir
1087
+
1088
+ @c1id = Fluent::UniqueId.generate
1089
+ p1 = File.join(@bufdir, "etest.201604171358.q#{Fluent::UniqueId.hex(@c1id)}.log")
1090
+ File.open(p1, 'wb') do |f|
1091
+ f.write ["t1.test", event_time('2016-04-17 13:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1092
+ f.write ["t2.test", event_time('2016-04-17 13:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1093
+ f.write ["t3.test", event_time('2016-04-17 13:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1094
+ f.write ["t4.test", event_time('2016-04-17 13:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1095
+ end
1096
+ FileUtils.touch(p1, mtime: Time.parse('2016-04-17 13:58:28 -0700'))
1097
+
1098
+ @not_chunk = File.join(@bufdir, 'etest.20160416.log')
1099
+ File.open(@not_chunk, 'wb') do |f|
1100
+ f.write ["t1.test", event_time('2016-04-16 23:58:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1101
+ f.write ["t2.test", event_time('2016-04-16 23:58:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1102
+ f.write ["t3.test", event_time('2016-04-16 23:58:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1103
+ f.write ["t4.test", event_time('2016-04-16 23:58:22 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1104
+ end
1105
+ FileUtils.touch(@not_chunk, mtime: Time.parse('2016-04-17 00:00:00 -0700'))
1106
+
1107
+ @bufpath = File.join(@bufdir, 'etest.*.log')
1108
+
1109
+ Fluent::Test.setup
1110
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
1111
+ @p = Fluent::Plugin::FileBuffer.new
1112
+ @p.owner = @d
1113
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
1114
+ @p.start
1115
+ end
1116
+
1117
+ teardown do
1118
+ if @p
1119
+ @p.stop unless @p.stopped?
1120
+ @p.before_shutdown unless @p.before_shutdown?
1121
+ @p.shutdown unless @p.shutdown?
1122
+ @p.after_shutdown unless @p.after_shutdown?
1123
+ @p.close unless @p.closed?
1124
+ @p.terminate unless @p.terminated?
1125
+ end
1126
+ if @bufdir
1127
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
1128
+ next if ['.', '..'].include?(File.basename(path))
1129
+ File.delete(path)
1130
+ end
1131
+ end
1132
+ end
1133
+
1134
+ test '#resume returns queued chunks for files without metadata, while ignoring non-chunk looking files' do
1135
+ assert_equal 0, @p.stage.size
1136
+ assert_equal 1, @p.queue.size
1137
+
1138
+ queue = @p.queue
1139
+
1140
+ m = metadata()
1141
+
1142
+ assert_equal @c1id, queue[0].unique_id
1143
+ assert_equal m, queue[0].metadata
1144
+ assert_equal 0, queue[0].size
1145
+ assert_equal :queued, queue[0].state
1146
+ assert_equal Time.parse('2016-04-17 13:58:28 -0700'), queue[0].modified_at
1147
+
1148
+ assert File.exist?(@not_chunk)
1149
+ end
1150
+ end
1151
+
1152
+ sub_test_case 'there are existing broken file chunks' do
1153
+ setup do
1154
+ @bufdir = File.expand_path('../../tmp/broken_buffer_file', __FILE__)
1155
+ FileUtils.mkdir_p @bufdir unless File.exist?(@bufdir)
1156
+ @bufpath = File.join(@bufdir, 'broken_test.*.log')
1157
+
1158
+ Fluent::Test.setup
1159
+ @d = FluentPluginFileBufferTest::DummyOutputPlugin.new
1160
+ @p = Fluent::Plugin::FileBuffer.new
1161
+ @p.owner = @d
1162
+ @p.configure(config_element('buffer', '', {'path' => @bufpath}))
1163
+ end
1164
+
1165
+ teardown do
1166
+ if @p
1167
+ @p.stop unless @p.stopped?
1168
+ @p.before_shutdown unless @p.before_shutdown?
1169
+ @p.shutdown unless @p.shutdown?
1170
+ @p.after_shutdown unless @p.after_shutdown?
1171
+ @p.close unless @p.closed?
1172
+ @p.terminate unless @p.terminated?
1173
+ end
1174
+ if @bufdir
1175
+ Dir.glob(File.join(@bufdir, '*')).each do |path|
1176
+ next if ['.', '..'].include?(File.basename(path))
1177
+ File.delete(path)
1178
+ end
1179
+ end
1180
+ end
1181
+
1182
+ def create_first_chunk(mode)
1183
+ cid = Fluent::UniqueId.generate
1184
+ path = File.join(@bufdir, "broken_test.#{mode}#{Fluent::UniqueId.hex(cid)}.log")
1185
+ File.open(path, 'wb') do |f|
1186
+ f.write ["t1.test", event_time('2016-04-17 14:00:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1187
+ f.write ["t2.test", event_time('2016-04-17 14:00:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1188
+ f.write ["t3.test", event_time('2016-04-17 14:00:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1189
+ f.write ["t4.test", event_time('2016-04-17 14:00:28 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1190
+ end
1191
+ write_metadata(
1192
+ path + '.meta', cid, metadata(timekey: event_time('2016-04-17 14:00:00 -0700').to_i),
1193
+ 4, event_time('2016-04-17 14:00:00 -0700').to_i, event_time('2016-04-17 14:00:28 -0700').to_i
1194
+ )
1195
+
1196
+ return cid, path
1197
+ end
1198
+
1199
+ def create_second_chunk(mode)
1200
+ cid = Fluent::UniqueId.generate
1201
+ path = File.join(@bufdir, "broken_test.#{mode}#{Fluent::UniqueId.hex(cid)}.log")
1202
+ File.open(path, 'wb') do |f|
1203
+ f.write ["t1.test", event_time('2016-04-17 14:01:15 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1204
+ f.write ["t2.test", event_time('2016-04-17 14:01:17 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1205
+ f.write ["t3.test", event_time('2016-04-17 14:01:21 -0700').to_i, {"message" => "yay"}].to_json + "\n"
1206
+ end
1207
+ write_metadata(
1208
+ path + '.meta', cid, metadata(timekey: event_time('2016-04-17 14:01:00 -0700').to_i),
1209
+ 3, event_time('2016-04-17 14:01:00 -0700').to_i, event_time('2016-04-17 14:01:25 -0700').to_i
1210
+ )
1211
+
1212
+ return cid, path
1213
+ end
1214
+
1215
+ def compare_staged_chunk(staged, id, time, num, mode)
1216
+ assert_equal 1, staged.size
1217
+ m = metadata(timekey: event_time(time).to_i)
1218
+ assert_equal id, staged[m].unique_id
1219
+ assert_equal num, staged[m].size
1220
+ assert_equal mode, staged[m].state
1221
+ end
1222
+
1223
+ def compare_queued_chunk(queued, id, num, mode)
1224
+ assert_equal 1, queued.size
1225
+ assert_equal id, queued[0].unique_id
1226
+ assert_equal num, queued[0].size
1227
+ assert_equal mode, queued[0].state
1228
+ end
1229
+
1230
+ def compare_log(plugin, msg)
1231
+ logs = plugin.log.out.logs
1232
+ assert { logs.any? { |log| log.include?(msg) } }
1233
+ end
1234
+
1235
+ test '#resume ignores staged empty chunk' do
1236
+ _, p1 = create_first_chunk('b')
1237
+ File.open(p1, 'wb') { |f| } # create staged empty chunk file
1238
+ c2id, _ = create_second_chunk('b')
1239
+
1240
+ @p.start
1241
+ compare_staged_chunk(@p.stage, c2id, '2016-04-17 14:01:00 -0700', 3, :staged)
1242
+ compare_log(@p, 'staged file chunk is empty')
1243
+ end
1244
+
1245
+ test '#resume ignores staged broken metadata' do
1246
+ c1id, _ = create_first_chunk('b')
1247
+ _, p2 = create_second_chunk('b')
1248
+ File.open(p2 + '.meta', 'wb') { |f| f.write("\0" * 70) } # create staged broken meta file
1249
+
1250
+ @p.start
1251
+ compare_staged_chunk(@p.stage, c1id, '2016-04-17 14:00:00 -0700', 4, :staged)
1252
+ compare_log(@p, 'staged meta file is broken')
1253
+ end
1254
+
1255
+ test '#resume ignores enqueued empty chunk' do
1256
+ _, p1 = create_first_chunk('q')
1257
+ File.open(p1, 'wb') { |f| } # create enqueued empty chunk file
1258
+ c2id, _ = create_second_chunk('q')
1259
+
1260
+ @p.start
1261
+ compare_queued_chunk(@p.queue, c2id, 3, :queued)
1262
+ compare_log(@p, 'enqueued file chunk is empty')
1263
+ end
1264
+
1265
+ test '#resume ignores enqueued broken metadata' do
1266
+ c1id, _ = create_first_chunk('q')
1267
+ _, p2 = create_second_chunk('q')
1268
+ File.open(p2 + '.meta', 'wb') { |f| f.write("\0" * 70) } # create enqueued broken meta file
1269
+
1270
+ @p.start
1271
+ compare_queued_chunk(@p.queue, c1id, 4, :queued)
1272
+ compare_log(@p, 'enqueued meta file is broken')
1273
+ end
1274
+ end
1275
+ end