dtomasgu-fluentd 1.14.7.pre.dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (564) hide show
  1. checksums.yaml +7 -0
  2. data/.deepsource.toml +13 -0
  3. data/.drone.yml +35 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.yaml +70 -0
  5. data/.github/ISSUE_TEMPLATE/config.yml +5 -0
  6. data/.github/ISSUE_TEMPLATE/feature_request.yaml +38 -0
  7. data/.github/ISSUE_TEMPLATE.md +17 -0
  8. data/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  9. data/.github/workflows/issue-auto-closer.yml +12 -0
  10. data/.github/workflows/linux-test.yaml +36 -0
  11. data/.github/workflows/macos-test.yaml +34 -0
  12. data/.github/workflows/stale-actions.yml +22 -0
  13. data/.github/workflows/windows-test.yaml +49 -0
  14. data/.gitignore +30 -0
  15. data/.gitlab-ci.yml +103 -0
  16. data/ADOPTERS.md +5 -0
  17. data/AUTHORS +2 -0
  18. data/CHANGELOG.md +2453 -0
  19. data/CONTRIBUTING.md +45 -0
  20. data/GOVERNANCE.md +55 -0
  21. data/Gemfile +9 -0
  22. data/GithubWorkflow.md +78 -0
  23. data/LICENSE +202 -0
  24. data/MAINTAINERS.md +11 -0
  25. data/README.md +76 -0
  26. data/Rakefile +79 -0
  27. data/SECURITY.md +18 -0
  28. data/bin/fluent-binlog-reader +7 -0
  29. data/bin/fluent-ca-generate +6 -0
  30. data/bin/fluent-cap-ctl +7 -0
  31. data/bin/fluent-cat +5 -0
  32. data/bin/fluent-ctl +7 -0
  33. data/bin/fluent-debug +5 -0
  34. data/bin/fluent-gem +9 -0
  35. data/bin/fluent-plugin-config-format +5 -0
  36. data/bin/fluent-plugin-generate +5 -0
  37. data/bin/fluentd +15 -0
  38. data/code-of-conduct.md +3 -0
  39. data/docs/SECURITY_AUDIT.pdf +0 -0
  40. data/example/copy_roundrobin.conf +39 -0
  41. data/example/counter.conf +18 -0
  42. data/example/filter_stdout.conf +22 -0
  43. data/example/in_forward.conf +14 -0
  44. data/example/in_forward_client.conf +37 -0
  45. data/example/in_forward_shared_key.conf +15 -0
  46. data/example/in_forward_tls.conf +14 -0
  47. data/example/in_forward_users.conf +24 -0
  48. data/example/in_forward_workers.conf +21 -0
  49. data/example/in_http.conf +16 -0
  50. data/example/in_out_forward.conf +17 -0
  51. data/example/in_sample_blocks.conf +17 -0
  52. data/example/in_sample_with_compression.conf +23 -0
  53. data/example/in_syslog.conf +15 -0
  54. data/example/in_tail.conf +14 -0
  55. data/example/in_tcp.conf +13 -0
  56. data/example/in_udp.conf +13 -0
  57. data/example/logevents.conf +25 -0
  58. data/example/multi_filters.conf +61 -0
  59. data/example/out_copy.conf +20 -0
  60. data/example/out_exec_filter.conf +42 -0
  61. data/example/out_file.conf +13 -0
  62. data/example/out_forward.conf +35 -0
  63. data/example/out_forward_buf_file.conf +23 -0
  64. data/example/out_forward_client.conf +109 -0
  65. data/example/out_forward_heartbeat_none.conf +16 -0
  66. data/example/out_forward_sd.conf +17 -0
  67. data/example/out_forward_shared_key.conf +36 -0
  68. data/example/out_forward_tls.conf +18 -0
  69. data/example/out_forward_users.conf +65 -0
  70. data/example/out_null.conf +36 -0
  71. data/example/sd.yaml +8 -0
  72. data/example/secondary_file.conf +42 -0
  73. data/example/suppress_config_dump.conf +7 -0
  74. data/example/v0_12_filter.conf +78 -0
  75. data/example/v1_literal_example.conf +36 -0
  76. data/example/worker_section.conf +36 -0
  77. data/fluent.conf +139 -0
  78. data/fluentd.gemspec +57 -0
  79. data/lib/fluent/agent.rb +168 -0
  80. data/lib/fluent/capability.rb +87 -0
  81. data/lib/fluent/clock.rb +66 -0
  82. data/lib/fluent/command/binlog_reader.rb +244 -0
  83. data/lib/fluent/command/bundler_injection.rb +45 -0
  84. data/lib/fluent/command/ca_generate.rb +184 -0
  85. data/lib/fluent/command/cap_ctl.rb +174 -0
  86. data/lib/fluent/command/cat.rb +365 -0
  87. data/lib/fluent/command/ctl.rb +180 -0
  88. data/lib/fluent/command/debug.rb +103 -0
  89. data/lib/fluent/command/fluentd.rb +388 -0
  90. data/lib/fluent/command/plugin_config_formatter.rb +308 -0
  91. data/lib/fluent/command/plugin_generator.rb +365 -0
  92. data/lib/fluent/compat/call_super_mixin.rb +76 -0
  93. data/lib/fluent/compat/detach_process_mixin.rb +33 -0
  94. data/lib/fluent/compat/exec_util.rb +129 -0
  95. data/lib/fluent/compat/file_util.rb +54 -0
  96. data/lib/fluent/compat/filter.rb +68 -0
  97. data/lib/fluent/compat/formatter.rb +111 -0
  98. data/lib/fluent/compat/formatter_utils.rb +85 -0
  99. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  100. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  101. data/lib/fluent/compat/input.rb +49 -0
  102. data/lib/fluent/compat/output.rb +721 -0
  103. data/lib/fluent/compat/output_chain.rb +60 -0
  104. data/lib/fluent/compat/parser.rb +310 -0
  105. data/lib/fluent/compat/parser_utils.rb +40 -0
  106. data/lib/fluent/compat/propagate_default.rb +62 -0
  107. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  108. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  109. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  110. data/lib/fluent/compat/socket_util.rb +165 -0
  111. data/lib/fluent/compat/string_util.rb +34 -0
  112. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  113. data/lib/fluent/compat/type_converter.rb +90 -0
  114. data/lib/fluent/config/basic_parser.rb +123 -0
  115. data/lib/fluent/config/configure_proxy.rb +424 -0
  116. data/lib/fluent/config/dsl.rb +152 -0
  117. data/lib/fluent/config/element.rb +265 -0
  118. data/lib/fluent/config/error.rb +44 -0
  119. data/lib/fluent/config/literal_parser.rb +286 -0
  120. data/lib/fluent/config/parser.rb +107 -0
  121. data/lib/fluent/config/section.rb +272 -0
  122. data/lib/fluent/config/types.rb +249 -0
  123. data/lib/fluent/config/v1_parser.rb +192 -0
  124. data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
  125. data/lib/fluent/config/yaml_parser/loader.rb +91 -0
  126. data/lib/fluent/config/yaml_parser/parser.rb +166 -0
  127. data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
  128. data/lib/fluent/config/yaml_parser.rb +56 -0
  129. data/lib/fluent/config.rb +89 -0
  130. data/lib/fluent/configurable.rb +201 -0
  131. data/lib/fluent/counter/base_socket.rb +44 -0
  132. data/lib/fluent/counter/client.rb +297 -0
  133. data/lib/fluent/counter/error.rb +86 -0
  134. data/lib/fluent/counter/mutex_hash.rb +163 -0
  135. data/lib/fluent/counter/server.rb +273 -0
  136. data/lib/fluent/counter/store.rb +205 -0
  137. data/lib/fluent/counter/validator.rb +145 -0
  138. data/lib/fluent/counter.rb +23 -0
  139. data/lib/fluent/daemon.rb +15 -0
  140. data/lib/fluent/daemonizer.rb +88 -0
  141. data/lib/fluent/engine.rb +253 -0
  142. data/lib/fluent/env.rb +40 -0
  143. data/lib/fluent/error.rb +34 -0
  144. data/lib/fluent/event.rb +326 -0
  145. data/lib/fluent/event_router.rb +315 -0
  146. data/lib/fluent/ext_monitor_require.rb +28 -0
  147. data/lib/fluent/filter.rb +21 -0
  148. data/lib/fluent/fluent_log_event_router.rb +141 -0
  149. data/lib/fluent/formatter.rb +23 -0
  150. data/lib/fluent/input.rb +21 -0
  151. data/lib/fluent/label.rb +46 -0
  152. data/lib/fluent/load.rb +34 -0
  153. data/lib/fluent/log.rb +713 -0
  154. data/lib/fluent/match.rb +187 -0
  155. data/lib/fluent/mixin.rb +31 -0
  156. data/lib/fluent/msgpack_factory.rb +106 -0
  157. data/lib/fluent/oj_options.rb +62 -0
  158. data/lib/fluent/output.rb +29 -0
  159. data/lib/fluent/output_chain.rb +23 -0
  160. data/lib/fluent/parser.rb +23 -0
  161. data/lib/fluent/plugin/bare_output.rb +104 -0
  162. data/lib/fluent/plugin/base.rb +197 -0
  163. data/lib/fluent/plugin/buf_file.rb +213 -0
  164. data/lib/fluent/plugin/buf_file_single.rb +225 -0
  165. data/lib/fluent/plugin/buf_memory.rb +34 -0
  166. data/lib/fluent/plugin/buffer/chunk.rb +240 -0
  167. data/lib/fluent/plugin/buffer/file_chunk.rb +413 -0
  168. data/lib/fluent/plugin/buffer/file_single_chunk.rb +311 -0
  169. data/lib/fluent/plugin/buffer/memory_chunk.rb +91 -0
  170. data/lib/fluent/plugin/buffer.rb +918 -0
  171. data/lib/fluent/plugin/compressable.rb +96 -0
  172. data/lib/fluent/plugin/exec_util.rb +22 -0
  173. data/lib/fluent/plugin/file_util.rb +22 -0
  174. data/lib/fluent/plugin/file_wrapper.rb +132 -0
  175. data/lib/fluent/plugin/filter.rb +127 -0
  176. data/lib/fluent/plugin/filter_grep.rb +189 -0
  177. data/lib/fluent/plugin/filter_parser.rb +130 -0
  178. data/lib/fluent/plugin/filter_record_transformer.rb +324 -0
  179. data/lib/fluent/plugin/filter_stdout.rb +53 -0
  180. data/lib/fluent/plugin/formatter.rb +75 -0
  181. data/lib/fluent/plugin/formatter_csv.rb +78 -0
  182. data/lib/fluent/plugin/formatter_hash.rb +35 -0
  183. data/lib/fluent/plugin/formatter_json.rb +59 -0
  184. data/lib/fluent/plugin/formatter_ltsv.rb +44 -0
  185. data/lib/fluent/plugin/formatter_msgpack.rb +33 -0
  186. data/lib/fluent/plugin/formatter_out_file.rb +53 -0
  187. data/lib/fluent/plugin/formatter_single_value.rb +36 -0
  188. data/lib/fluent/plugin/formatter_stdout.rb +76 -0
  189. data/lib/fluent/plugin/formatter_tsv.rb +40 -0
  190. data/lib/fluent/plugin/in_debug_agent.rb +71 -0
  191. data/lib/fluent/plugin/in_dummy.rb +18 -0
  192. data/lib/fluent/plugin/in_exec.rb +110 -0
  193. data/lib/fluent/plugin/in_forward.rb +473 -0
  194. data/lib/fluent/plugin/in_gc_stat.rb +72 -0
  195. data/lib/fluent/plugin/in_http.rb +677 -0
  196. data/lib/fluent/plugin/in_monitor_agent.rb +412 -0
  197. data/lib/fluent/plugin/in_object_space.rb +93 -0
  198. data/lib/fluent/plugin/in_sample.rb +141 -0
  199. data/lib/fluent/plugin/in_syslog.rb +276 -0
  200. data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
  201. data/lib/fluent/plugin/in_tail/position_file.rb +255 -0
  202. data/lib/fluent/plugin/in_tail.rb +1247 -0
  203. data/lib/fluent/plugin/in_tcp.rb +181 -0
  204. data/lib/fluent/plugin/in_udp.rb +92 -0
  205. data/lib/fluent/plugin/in_unix.rb +195 -0
  206. data/lib/fluent/plugin/input.rb +75 -0
  207. data/lib/fluent/plugin/metrics.rb +119 -0
  208. data/lib/fluent/plugin/metrics_local.rb +96 -0
  209. data/lib/fluent/plugin/multi_output.rb +195 -0
  210. data/lib/fluent/plugin/out_copy.rb +120 -0
  211. data/lib/fluent/plugin/out_exec.rb +105 -0
  212. data/lib/fluent/plugin/out_exec_filter.rb +319 -0
  213. data/lib/fluent/plugin/out_file.rb +334 -0
  214. data/lib/fluent/plugin/out_forward/ack_handler.rb +161 -0
  215. data/lib/fluent/plugin/out_forward/connection_manager.rb +113 -0
  216. data/lib/fluent/plugin/out_forward/error.rb +28 -0
  217. data/lib/fluent/plugin/out_forward/failure_detector.rb +84 -0
  218. data/lib/fluent/plugin/out_forward/handshake_protocol.rb +125 -0
  219. data/lib/fluent/plugin/out_forward/load_balancer.rb +114 -0
  220. data/lib/fluent/plugin/out_forward/socket_cache.rb +142 -0
  221. data/lib/fluent/plugin/out_forward.rb +826 -0
  222. data/lib/fluent/plugin/out_http.rb +280 -0
  223. data/lib/fluent/plugin/out_null.rb +74 -0
  224. data/lib/fluent/plugin/out_relabel.rb +32 -0
  225. data/lib/fluent/plugin/out_roundrobin.rb +84 -0
  226. data/lib/fluent/plugin/out_secondary_file.rb +131 -0
  227. data/lib/fluent/plugin/out_stdout.rb +74 -0
  228. data/lib/fluent/plugin/out_stream.rb +130 -0
  229. data/lib/fluent/plugin/output.rb +1566 -0
  230. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  231. data/lib/fluent/plugin/parser.rb +274 -0
  232. data/lib/fluent/plugin/parser_apache.rb +28 -0
  233. data/lib/fluent/plugin/parser_apache2.rb +88 -0
  234. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  235. data/lib/fluent/plugin/parser_csv.rb +114 -0
  236. data/lib/fluent/plugin/parser_json.rb +96 -0
  237. data/lib/fluent/plugin/parser_ltsv.rb +51 -0
  238. data/lib/fluent/plugin/parser_msgpack.rb +50 -0
  239. data/lib/fluent/plugin/parser_multiline.rb +152 -0
  240. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  241. data/lib/fluent/plugin/parser_none.rb +36 -0
  242. data/lib/fluent/plugin/parser_regexp.rb +68 -0
  243. data/lib/fluent/plugin/parser_syslog.rb +496 -0
  244. data/lib/fluent/plugin/parser_tsv.rb +42 -0
  245. data/lib/fluent/plugin/sd_file.rb +156 -0
  246. data/lib/fluent/plugin/sd_srv.rb +135 -0
  247. data/lib/fluent/plugin/sd_static.rb +58 -0
  248. data/lib/fluent/plugin/service_discovery.rb +65 -0
  249. data/lib/fluent/plugin/socket_util.rb +22 -0
  250. data/lib/fluent/plugin/storage.rb +84 -0
  251. data/lib/fluent/plugin/storage_local.rb +162 -0
  252. data/lib/fluent/plugin/string_util.rb +22 -0
  253. data/lib/fluent/plugin.rb +206 -0
  254. data/lib/fluent/plugin_helper/cert_option.rb +191 -0
  255. data/lib/fluent/plugin_helper/child_process.rb +366 -0
  256. data/lib/fluent/plugin_helper/compat_parameters.rb +343 -0
  257. data/lib/fluent/plugin_helper/counter.rb +51 -0
  258. data/lib/fluent/plugin_helper/event_emitter.rb +100 -0
  259. data/lib/fluent/plugin_helper/event_loop.rb +170 -0
  260. data/lib/fluent/plugin_helper/extract.rb +104 -0
  261. data/lib/fluent/plugin_helper/formatter.rb +147 -0
  262. data/lib/fluent/plugin_helper/http_server/app.rb +79 -0
  263. data/lib/fluent/plugin_helper/http_server/compat/server.rb +92 -0
  264. data/lib/fluent/plugin_helper/http_server/compat/ssl_context_extractor.rb +52 -0
  265. data/lib/fluent/plugin_helper/http_server/compat/webrick_handler.rb +58 -0
  266. data/lib/fluent/plugin_helper/http_server/methods.rb +35 -0
  267. data/lib/fluent/plugin_helper/http_server/request.rb +42 -0
  268. data/lib/fluent/plugin_helper/http_server/router.rb +54 -0
  269. data/lib/fluent/plugin_helper/http_server/server.rb +93 -0
  270. data/lib/fluent/plugin_helper/http_server/ssl_context_builder.rb +41 -0
  271. data/lib/fluent/plugin_helper/http_server.rb +135 -0
  272. data/lib/fluent/plugin_helper/inject.rb +154 -0
  273. data/lib/fluent/plugin_helper/metrics.rb +129 -0
  274. data/lib/fluent/plugin_helper/parser.rb +147 -0
  275. data/lib/fluent/plugin_helper/record_accessor.rb +207 -0
  276. data/lib/fluent/plugin_helper/retry_state.rb +219 -0
  277. data/lib/fluent/plugin_helper/server.rb +820 -0
  278. data/lib/fluent/plugin_helper/service_discovery/manager.rb +146 -0
  279. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  280. data/lib/fluent/plugin_helper/service_discovery.rb +125 -0
  281. data/lib/fluent/plugin_helper/socket.rb +288 -0
  282. data/lib/fluent/plugin_helper/socket_option.rb +98 -0
  283. data/lib/fluent/plugin_helper/storage.rb +349 -0
  284. data/lib/fluent/plugin_helper/thread.rb +180 -0
  285. data/lib/fluent/plugin_helper/timer.rb +92 -0
  286. data/lib/fluent/plugin_helper.rb +75 -0
  287. data/lib/fluent/plugin_id.rb +93 -0
  288. data/lib/fluent/process.rb +22 -0
  289. data/lib/fluent/registry.rb +117 -0
  290. data/lib/fluent/root_agent.rb +372 -0
  291. data/lib/fluent/rpc.rb +95 -0
  292. data/lib/fluent/static_config_analysis.rb +194 -0
  293. data/lib/fluent/supervisor.rb +1141 -0
  294. data/lib/fluent/system_config.rb +188 -0
  295. data/lib/fluent/test/base.rb +78 -0
  296. data/lib/fluent/test/driver/base.rb +225 -0
  297. data/lib/fluent/test/driver/base_owned.rb +83 -0
  298. data/lib/fluent/test/driver/base_owner.rb +135 -0
  299. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  300. data/lib/fluent/test/driver/filter.rb +57 -0
  301. data/lib/fluent/test/driver/formatter.rb +30 -0
  302. data/lib/fluent/test/driver/input.rb +31 -0
  303. data/lib/fluent/test/driver/multi_output.rb +53 -0
  304. data/lib/fluent/test/driver/output.rb +102 -0
  305. data/lib/fluent/test/driver/parser.rb +30 -0
  306. data/lib/fluent/test/driver/storage.rb +30 -0
  307. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  308. data/lib/fluent/test/filter_test.rb +77 -0
  309. data/lib/fluent/test/formatter_test.rb +65 -0
  310. data/lib/fluent/test/helpers.rb +134 -0
  311. data/lib/fluent/test/input_test.rb +174 -0
  312. data/lib/fluent/test/log.rb +79 -0
  313. data/lib/fluent/test/output_test.rb +156 -0
  314. data/lib/fluent/test/parser_test.rb +70 -0
  315. data/lib/fluent/test/startup_shutdown.rb +46 -0
  316. data/lib/fluent/test.rb +58 -0
  317. data/lib/fluent/time.rb +512 -0
  318. data/lib/fluent/timezone.rb +171 -0
  319. data/lib/fluent/tls.rb +81 -0
  320. data/lib/fluent/unique_id.rb +39 -0
  321. data/lib/fluent/variable_store.rb +40 -0
  322. data/lib/fluent/version.rb +21 -0
  323. data/lib/fluent/winsvc.rb +105 -0
  324. data/templates/new_gem/Gemfile +3 -0
  325. data/templates/new_gem/README.md.erb +43 -0
  326. data/templates/new_gem/Rakefile +13 -0
  327. data/templates/new_gem/fluent-plugin.gemspec.erb +27 -0
  328. data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
  329. data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
  330. data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
  331. data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
  332. data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
  333. data/templates/new_gem/lib/fluent/plugin/storage.rb.erb +40 -0
  334. data/templates/new_gem/test/helper.rb.erb +8 -0
  335. data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
  336. data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
  337. data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
  338. data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
  339. data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
  340. data/templates/new_gem/test/plugin/test_storage.rb.erb +18 -0
  341. data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
  342. data/templates/plugin_config_formatter/param.md-table.erb +10 -0
  343. data/templates/plugin_config_formatter/param.md.erb +34 -0
  344. data/templates/plugin_config_formatter/section.md.erb +12 -0
  345. data/test/command/test_binlog_reader.rb +362 -0
  346. data/test/command/test_ca_generate.rb +70 -0
  347. data/test/command/test_cap_ctl.rb +100 -0
  348. data/test/command/test_cat.rb +128 -0
  349. data/test/command/test_ctl.rb +56 -0
  350. data/test/command/test_fluentd.rb +1139 -0
  351. data/test/command/test_plugin_config_formatter.rb +398 -0
  352. data/test/command/test_plugin_generator.rb +109 -0
  353. data/test/compat/test_calls_super.rb +166 -0
  354. data/test/compat/test_parser.rb +92 -0
  355. data/test/config/assertions.rb +42 -0
  356. data/test/config/test_config_parser.rb +551 -0
  357. data/test/config/test_configurable.rb +1784 -0
  358. data/test/config/test_configure_proxy.rb +604 -0
  359. data/test/config/test_dsl.rb +415 -0
  360. data/test/config/test_element.rb +518 -0
  361. data/test/config/test_literal_parser.rb +309 -0
  362. data/test/config/test_plugin_configuration.rb +56 -0
  363. data/test/config/test_section.rb +191 -0
  364. data/test/config/test_system_config.rb +201 -0
  365. data/test/config/test_types.rb +408 -0
  366. data/test/counter/test_client.rb +563 -0
  367. data/test/counter/test_error.rb +44 -0
  368. data/test/counter/test_mutex_hash.rb +179 -0
  369. data/test/counter/test_server.rb +589 -0
  370. data/test/counter/test_store.rb +258 -0
  371. data/test/counter/test_validator.rb +137 -0
  372. data/test/helper.rb +155 -0
  373. data/test/helpers/fuzzy_assert.rb +89 -0
  374. data/test/helpers/process_extenstion.rb +33 -0
  375. data/test/plugin/data/2010/01/20100102-030405.log +0 -0
  376. data/test/plugin/data/2010/01/20100102-030406.log +0 -0
  377. data/test/plugin/data/2010/01/20100102.log +0 -0
  378. data/test/plugin/data/log/bar +0 -0
  379. data/test/plugin/data/log/foo/bar.log +0 -0
  380. data/test/plugin/data/log/foo/bar2 +0 -0
  381. data/test/plugin/data/log/test.log +0 -0
  382. data/test/plugin/data/sd_file/config +11 -0
  383. data/test/plugin/data/sd_file/config.json +17 -0
  384. data/test/plugin/data/sd_file/config.yaml +11 -0
  385. data/test/plugin/data/sd_file/config.yml +11 -0
  386. data/test/plugin/data/sd_file/invalid_config.yml +7 -0
  387. data/test/plugin/in_tail/test_fifo.rb +121 -0
  388. data/test/plugin/in_tail/test_io_handler.rb +150 -0
  389. data/test/plugin/in_tail/test_position_file.rb +316 -0
  390. data/test/plugin/out_forward/test_ack_handler.rb +101 -0
  391. data/test/plugin/out_forward/test_connection_manager.rb +145 -0
  392. data/test/plugin/out_forward/test_handshake_protocol.rb +112 -0
  393. data/test/plugin/out_forward/test_load_balancer.rb +106 -0
  394. data/test/plugin/out_forward/test_socket_cache.rb +174 -0
  395. data/test/plugin/test_bare_output.rb +131 -0
  396. data/test/plugin/test_base.rb +115 -0
  397. data/test/plugin/test_buf_file.rb +1275 -0
  398. data/test/plugin/test_buf_file_single.rb +833 -0
  399. data/test/plugin/test_buf_memory.rb +42 -0
  400. data/test/plugin/test_buffer.rb +1383 -0
  401. data/test/plugin/test_buffer_chunk.rb +198 -0
  402. data/test/plugin/test_buffer_file_chunk.rb +871 -0
  403. data/test/plugin/test_buffer_file_single_chunk.rb +611 -0
  404. data/test/plugin/test_buffer_memory_chunk.rb +339 -0
  405. data/test/plugin/test_compressable.rb +87 -0
  406. data/test/plugin/test_file_util.rb +96 -0
  407. data/test/plugin/test_file_wrapper.rb +58 -0
  408. data/test/plugin/test_filter.rb +368 -0
  409. data/test/plugin/test_filter_grep.rb +697 -0
  410. data/test/plugin/test_filter_parser.rb +731 -0
  411. data/test/plugin/test_filter_record_transformer.rb +577 -0
  412. data/test/plugin/test_filter_stdout.rb +207 -0
  413. data/test/plugin/test_formatter_csv.rb +136 -0
  414. data/test/plugin/test_formatter_hash.rb +38 -0
  415. data/test/plugin/test_formatter_json.rb +61 -0
  416. data/test/plugin/test_formatter_ltsv.rb +70 -0
  417. data/test/plugin/test_formatter_msgpack.rb +28 -0
  418. data/test/plugin/test_formatter_out_file.rb +116 -0
  419. data/test/plugin/test_formatter_single_value.rb +44 -0
  420. data/test/plugin/test_formatter_tsv.rb +76 -0
  421. data/test/plugin/test_in_debug_agent.rb +49 -0
  422. data/test/plugin/test_in_exec.rb +261 -0
  423. data/test/plugin/test_in_forward.rb +1178 -0
  424. data/test/plugin/test_in_gc_stat.rb +62 -0
  425. data/test/plugin/test_in_http.rb +1103 -0
  426. data/test/plugin/test_in_monitor_agent.rb +923 -0
  427. data/test/plugin/test_in_object_space.rb +66 -0
  428. data/test/plugin/test_in_sample.rb +190 -0
  429. data/test/plugin/test_in_syslog.rb +505 -0
  430. data/test/plugin/test_in_tail.rb +2639 -0
  431. data/test/plugin/test_in_tcp.rb +243 -0
  432. data/test/plugin/test_in_udp.rb +268 -0
  433. data/test/plugin/test_in_unix.rb +181 -0
  434. data/test/plugin/test_input.rb +137 -0
  435. data/test/plugin/test_metadata.rb +89 -0
  436. data/test/plugin/test_metrics.rb +294 -0
  437. data/test/plugin/test_metrics_local.rb +96 -0
  438. data/test/plugin/test_multi_output.rb +204 -0
  439. data/test/plugin/test_out_copy.rb +308 -0
  440. data/test/plugin/test_out_exec.rb +312 -0
  441. data/test/plugin/test_out_exec_filter.rb +606 -0
  442. data/test/plugin/test_out_file.rb +1037 -0
  443. data/test/plugin/test_out_forward.rb +1358 -0
  444. data/test/plugin/test_out_http.rb +428 -0
  445. data/test/plugin/test_out_null.rb +105 -0
  446. data/test/plugin/test_out_relabel.rb +28 -0
  447. data/test/plugin/test_out_roundrobin.rb +146 -0
  448. data/test/plugin/test_out_secondary_file.rb +458 -0
  449. data/test/plugin/test_out_stdout.rb +205 -0
  450. data/test/plugin/test_out_stream.rb +103 -0
  451. data/test/plugin/test_output.rb +1065 -0
  452. data/test/plugin/test_output_as_buffered.rb +2024 -0
  453. data/test/plugin/test_output_as_buffered_backup.rb +363 -0
  454. data/test/plugin/test_output_as_buffered_compress.rb +165 -0
  455. data/test/plugin/test_output_as_buffered_overflow.rb +250 -0
  456. data/test/plugin/test_output_as_buffered_retries.rb +966 -0
  457. data/test/plugin/test_output_as_buffered_secondary.rb +882 -0
  458. data/test/plugin/test_output_as_standard.rb +374 -0
  459. data/test/plugin/test_owned_by.rb +35 -0
  460. data/test/plugin/test_parser.rb +399 -0
  461. data/test/plugin/test_parser_apache.rb +42 -0
  462. data/test/plugin/test_parser_apache2.rb +47 -0
  463. data/test/plugin/test_parser_apache_error.rb +45 -0
  464. data/test/plugin/test_parser_csv.rb +200 -0
  465. data/test/plugin/test_parser_json.rb +138 -0
  466. data/test/plugin/test_parser_labeled_tsv.rb +160 -0
  467. data/test/plugin/test_parser_multiline.rb +111 -0
  468. data/test/plugin/test_parser_nginx.rb +88 -0
  469. data/test/plugin/test_parser_none.rb +52 -0
  470. data/test/plugin/test_parser_regexp.rb +289 -0
  471. data/test/plugin/test_parser_syslog.rb +650 -0
  472. data/test/plugin/test_parser_tsv.rb +122 -0
  473. data/test/plugin/test_sd_file.rb +228 -0
  474. data/test/plugin/test_sd_srv.rb +230 -0
  475. data/test/plugin/test_storage.rb +167 -0
  476. data/test/plugin/test_storage_local.rb +335 -0
  477. data/test/plugin/test_string_util.rb +26 -0
  478. data/test/plugin_helper/data/cert/cert-key.pem +27 -0
  479. data/test/plugin_helper/data/cert/cert-with-CRLF.pem +19 -0
  480. data/test/plugin_helper/data/cert/cert-with-no-newline.pem +19 -0
  481. data/test/plugin_helper/data/cert/cert.pem +19 -0
  482. data/test/plugin_helper/data/cert/cert_chains/ca-cert-key.pem +27 -0
  483. data/test/plugin_helper/data/cert/cert_chains/ca-cert.pem +20 -0
  484. data/test/plugin_helper/data/cert/cert_chains/cert-key.pem +27 -0
  485. data/test/plugin_helper/data/cert/cert_chains/cert.pem +40 -0
  486. data/test/plugin_helper/data/cert/empty.pem +0 -0
  487. data/test/plugin_helper/data/cert/generate_cert.rb +125 -0
  488. data/test/plugin_helper/data/cert/with_ca/ca-cert-key-pass.pem +30 -0
  489. data/test/plugin_helper/data/cert/with_ca/ca-cert-key.pem +27 -0
  490. data/test/plugin_helper/data/cert/with_ca/ca-cert-pass.pem +20 -0
  491. data/test/plugin_helper/data/cert/with_ca/ca-cert.pem +20 -0
  492. data/test/plugin_helper/data/cert/with_ca/cert-key-pass.pem +30 -0
  493. data/test/plugin_helper/data/cert/with_ca/cert-key.pem +27 -0
  494. data/test/plugin_helper/data/cert/with_ca/cert-pass.pem +21 -0
  495. data/test/plugin_helper/data/cert/with_ca/cert.pem +21 -0
  496. data/test/plugin_helper/data/cert/without_ca/cert-key-pass.pem +30 -0
  497. data/test/plugin_helper/data/cert/without_ca/cert-key.pem +27 -0
  498. data/test/plugin_helper/data/cert/without_ca/cert-pass.pem +20 -0
  499. data/test/plugin_helper/data/cert/without_ca/cert.pem +20 -0
  500. data/test/plugin_helper/http_server/test_app.rb +65 -0
  501. data/test/plugin_helper/http_server/test_route.rb +32 -0
  502. data/test/plugin_helper/service_discovery/test_manager.rb +93 -0
  503. data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +21 -0
  504. data/test/plugin_helper/test_cert_option.rb +25 -0
  505. data/test/plugin_helper/test_child_process.rb +852 -0
  506. data/test/plugin_helper/test_compat_parameters.rb +358 -0
  507. data/test/plugin_helper/test_event_emitter.rb +80 -0
  508. data/test/plugin_helper/test_event_loop.rb +52 -0
  509. data/test/plugin_helper/test_extract.rb +194 -0
  510. data/test/plugin_helper/test_formatter.rb +255 -0
  511. data/test/plugin_helper/test_http_server_helper.rb +372 -0
  512. data/test/plugin_helper/test_inject.rb +561 -0
  513. data/test/plugin_helper/test_metrics.rb +137 -0
  514. data/test/plugin_helper/test_parser.rb +264 -0
  515. data/test/plugin_helper/test_record_accessor.rb +238 -0
  516. data/test/plugin_helper/test_retry_state.rb +1006 -0
  517. data/test/plugin_helper/test_server.rb +1841 -0
  518. data/test/plugin_helper/test_service_discovery.rb +165 -0
  519. data/test/plugin_helper/test_socket.rb +146 -0
  520. data/test/plugin_helper/test_storage.rb +542 -0
  521. data/test/plugin_helper/test_thread.rb +164 -0
  522. data/test/plugin_helper/test_timer.rb +130 -0
  523. data/test/scripts/exec_script.rb +32 -0
  524. data/test/scripts/fluent/plugin/formatter1/formatter_test1.rb +7 -0
  525. data/test/scripts/fluent/plugin/formatter2/formatter_test2.rb +7 -0
  526. data/test/scripts/fluent/plugin/formatter_known.rb +8 -0
  527. data/test/scripts/fluent/plugin/out_test.rb +81 -0
  528. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  529. data/test/scripts/fluent/plugin/parser_known.rb +4 -0
  530. data/test/test_capability.rb +74 -0
  531. data/test/test_clock.rb +164 -0
  532. data/test/test_config.rb +333 -0
  533. data/test/test_configdsl.rb +148 -0
  534. data/test/test_daemonizer.rb +91 -0
  535. data/test/test_engine.rb +203 -0
  536. data/test/test_event.rb +531 -0
  537. data/test/test_event_router.rb +348 -0
  538. data/test/test_event_time.rb +199 -0
  539. data/test/test_filter.rb +121 -0
  540. data/test/test_fluent_log_event_router.rb +99 -0
  541. data/test/test_formatter.rb +366 -0
  542. data/test/test_input.rb +31 -0
  543. data/test/test_log.rb +994 -0
  544. data/test/test_logger_initializer.rb +46 -0
  545. data/test/test_match.rb +148 -0
  546. data/test/test_mixin.rb +351 -0
  547. data/test/test_msgpack_factory.rb +18 -0
  548. data/test/test_oj_options.rb +55 -0
  549. data/test/test_output.rb +278 -0
  550. data/test/test_plugin.rb +251 -0
  551. data/test/test_plugin_classes.rb +370 -0
  552. data/test/test_plugin_helper.rb +81 -0
  553. data/test/test_plugin_id.rb +119 -0
  554. data/test/test_process.rb +14 -0
  555. data/test/test_root_agent.rb +951 -0
  556. data/test/test_static_config_analysis.rb +177 -0
  557. data/test/test_supervisor.rb +791 -0
  558. data/test/test_test_drivers.rb +136 -0
  559. data/test/test_time_formatter.rb +301 -0
  560. data/test/test_time_parser.rb +362 -0
  561. data/test/test_tls.rb +65 -0
  562. data/test/test_unique_id.rb +47 -0
  563. data/test/test_variable_store.rb +65 -0
  564. metadata +1191 -0
@@ -0,0 +1,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