fluentd 1.17.0-x64-mingw-ucrt → 1.18.0-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (278) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +100 -0
  3. data/README.md +1 -0
  4. data/SECURITY.md +2 -2
  5. data/fluent.conf +14 -14
  6. data/lib/fluent/command/cap_ctl.rb +4 -4
  7. data/lib/fluent/command/fluentd.rb +7 -1
  8. data/lib/fluent/compat/call_super_mixin.rb +3 -3
  9. data/lib/fluent/compat/propagate_default.rb +4 -4
  10. data/lib/fluent/config/literal_parser.rb +9 -2
  11. data/lib/fluent/config/yaml_parser/parser.rb +4 -0
  12. data/lib/fluent/engine.rb +49 -33
  13. data/lib/fluent/env.rb +3 -0
  14. data/lib/fluent/event_router.rb +2 -2
  15. data/lib/fluent/log/console_adapter.rb +4 -2
  16. data/lib/fluent/plugin/filter_parser.rb +27 -51
  17. data/lib/fluent/plugin/in_exec.rb +14 -2
  18. data/lib/fluent/plugin/in_http.rb +6 -1
  19. data/lib/fluent/plugin/in_sample.rb +13 -7
  20. data/lib/fluent/plugin/in_syslog.rb +4 -0
  21. data/lib/fluent/plugin/in_tail.rb +65 -23
  22. data/lib/fluent/plugin/in_tcp.rb +4 -0
  23. data/lib/fluent/plugin/in_udp.rb +10 -1
  24. data/lib/fluent/plugin/input.rb +4 -0
  25. data/lib/fluent/plugin/out_buffer.rb +40 -0
  26. data/lib/fluent/plugin/out_copy.rb +1 -1
  27. data/lib/fluent/plugin/out_file.rb +8 -0
  28. data/lib/fluent/plugin/out_http.rb +12 -0
  29. data/lib/fluent/plugin/output.rb +2 -0
  30. data/lib/fluent/plugin/parser_json.rb +4 -12
  31. data/lib/fluent/plugin_helper/cert_option.rb +8 -0
  32. data/lib/fluent/plugin_helper/event_emitter.rb +12 -0
  33. data/lib/fluent/plugin_helper/http_server/server.rb +24 -8
  34. data/lib/fluent/plugin_helper/server.rb +9 -0
  35. data/lib/fluent/root_agent.rb +114 -19
  36. data/lib/fluent/source_only_buffer_agent.rb +102 -0
  37. data/lib/fluent/supervisor.rb +207 -34
  38. data/lib/fluent/system_config.rb +15 -3
  39. data/lib/fluent/version.rb +1 -1
  40. data/templates/new_gem/fluent-plugin.gemspec.erb +6 -5
  41. metadata +24 -483
  42. data/.github/DISCUSSION_TEMPLATE/q-a-japanese.yml +0 -50
  43. data/.github/DISCUSSION_TEMPLATE/q-a.yml +0 -47
  44. data/.github/ISSUE_TEMPLATE/bug_report.yml +0 -71
  45. data/.github/ISSUE_TEMPLATE/config.yml +0 -5
  46. data/.github/ISSUE_TEMPLATE/feature_request.yml +0 -39
  47. data/.github/ISSUE_TEMPLATE.md +0 -17
  48. data/.github/PULL_REQUEST_TEMPLATE.md +0 -14
  49. data/.github/workflows/stale-actions.yml +0 -24
  50. data/.github/workflows/test-ruby-head.yml +0 -31
  51. data/.github/workflows/test.yml +0 -32
  52. data/.gitignore +0 -30
  53. data/Gemfile +0 -9
  54. data/fluentd.gemspec +0 -62
  55. data/test/command/test_binlog_reader.rb +0 -362
  56. data/test/command/test_ca_generate.rb +0 -70
  57. data/test/command/test_cap_ctl.rb +0 -100
  58. data/test/command/test_cat.rb +0 -128
  59. data/test/command/test_ctl.rb +0 -56
  60. data/test/command/test_fluentd.rb +0 -1291
  61. data/test/command/test_plugin_config_formatter.rb +0 -397
  62. data/test/command/test_plugin_generator.rb +0 -109
  63. data/test/compat/test_calls_super.rb +0 -166
  64. data/test/compat/test_parser.rb +0 -92
  65. data/test/config/assertions.rb +0 -42
  66. data/test/config/test_config_parser.rb +0 -551
  67. data/test/config/test_configurable.rb +0 -1784
  68. data/test/config/test_configure_proxy.rb +0 -604
  69. data/test/config/test_dsl.rb +0 -415
  70. data/test/config/test_element.rb +0 -518
  71. data/test/config/test_literal_parser.rb +0 -309
  72. data/test/config/test_plugin_configuration.rb +0 -56
  73. data/test/config/test_section.rb +0 -191
  74. data/test/config/test_system_config.rb +0 -195
  75. data/test/config/test_types.rb +0 -408
  76. data/test/counter/test_client.rb +0 -563
  77. data/test/counter/test_error.rb +0 -44
  78. data/test/counter/test_mutex_hash.rb +0 -179
  79. data/test/counter/test_server.rb +0 -589
  80. data/test/counter/test_store.rb +0 -258
  81. data/test/counter/test_validator.rb +0 -137
  82. data/test/helper.rb +0 -155
  83. data/test/helpers/fuzzy_assert.rb +0 -89
  84. data/test/helpers/process_extenstion.rb +0 -33
  85. data/test/log/test_console_adapter.rb +0 -117
  86. data/test/plugin/data/2010/01/20100102-030405.log +0 -0
  87. data/test/plugin/data/2010/01/20100102-030406.log +0 -0
  88. data/test/plugin/data/2010/01/20100102.log +0 -0
  89. data/test/plugin/data/log/bar +0 -0
  90. data/test/plugin/data/log/foo/bar.log +0 -0
  91. data/test/plugin/data/log/foo/bar2 +0 -0
  92. data/test/plugin/data/log/test.log +0 -0
  93. data/test/plugin/data/log_numeric/01.log +0 -0
  94. data/test/plugin/data/log_numeric/02.log +0 -0
  95. data/test/plugin/data/log_numeric/12.log +0 -0
  96. data/test/plugin/data/log_numeric/14.log +0 -0
  97. data/test/plugin/data/sd_file/config +0 -11
  98. data/test/plugin/data/sd_file/config.json +0 -17
  99. data/test/plugin/data/sd_file/config.yaml +0 -11
  100. data/test/plugin/data/sd_file/config.yml +0 -11
  101. data/test/plugin/data/sd_file/invalid_config.yml +0 -7
  102. data/test/plugin/in_tail/test_fifo.rb +0 -121
  103. data/test/plugin/in_tail/test_io_handler.rb +0 -150
  104. data/test/plugin/in_tail/test_position_file.rb +0 -346
  105. data/test/plugin/out_forward/test_ack_handler.rb +0 -140
  106. data/test/plugin/out_forward/test_connection_manager.rb +0 -145
  107. data/test/plugin/out_forward/test_handshake_protocol.rb +0 -112
  108. data/test/plugin/out_forward/test_load_balancer.rb +0 -106
  109. data/test/plugin/out_forward/test_socket_cache.rb +0 -174
  110. data/test/plugin/test_bare_output.rb +0 -131
  111. data/test/plugin/test_base.rb +0 -247
  112. data/test/plugin/test_buf_file.rb +0 -1314
  113. data/test/plugin/test_buf_file_single.rb +0 -898
  114. data/test/plugin/test_buf_memory.rb +0 -42
  115. data/test/plugin/test_buffer.rb +0 -1493
  116. data/test/plugin/test_buffer_chunk.rb +0 -209
  117. data/test/plugin/test_buffer_file_chunk.rb +0 -871
  118. data/test/plugin/test_buffer_file_single_chunk.rb +0 -611
  119. data/test/plugin/test_buffer_memory_chunk.rb +0 -339
  120. data/test/plugin/test_compressable.rb +0 -87
  121. data/test/plugin/test_file_util.rb +0 -96
  122. data/test/plugin/test_filter.rb +0 -368
  123. data/test/plugin/test_filter_grep.rb +0 -697
  124. data/test/plugin/test_filter_parser.rb +0 -731
  125. data/test/plugin/test_filter_record_transformer.rb +0 -577
  126. data/test/plugin/test_filter_stdout.rb +0 -207
  127. data/test/plugin/test_formatter_csv.rb +0 -136
  128. data/test/plugin/test_formatter_hash.rb +0 -38
  129. data/test/plugin/test_formatter_json.rb +0 -61
  130. data/test/plugin/test_formatter_ltsv.rb +0 -70
  131. data/test/plugin/test_formatter_msgpack.rb +0 -28
  132. data/test/plugin/test_formatter_out_file.rb +0 -116
  133. data/test/plugin/test_formatter_single_value.rb +0 -44
  134. data/test/plugin/test_formatter_tsv.rb +0 -76
  135. data/test/plugin/test_in_debug_agent.rb +0 -49
  136. data/test/plugin/test_in_exec.rb +0 -261
  137. data/test/plugin/test_in_forward.rb +0 -1178
  138. data/test/plugin/test_in_gc_stat.rb +0 -62
  139. data/test/plugin/test_in_http.rb +0 -1124
  140. data/test/plugin/test_in_monitor_agent.rb +0 -922
  141. data/test/plugin/test_in_object_space.rb +0 -66
  142. data/test/plugin/test_in_sample.rb +0 -190
  143. data/test/plugin/test_in_syslog.rb +0 -505
  144. data/test/plugin/test_in_tail.rb +0 -3429
  145. data/test/plugin/test_in_tcp.rb +0 -328
  146. data/test/plugin/test_in_udp.rb +0 -296
  147. data/test/plugin/test_in_unix.rb +0 -181
  148. data/test/plugin/test_input.rb +0 -137
  149. data/test/plugin/test_metadata.rb +0 -89
  150. data/test/plugin/test_metrics.rb +0 -294
  151. data/test/plugin/test_metrics_local.rb +0 -96
  152. data/test/plugin/test_multi_output.rb +0 -204
  153. data/test/plugin/test_out_copy.rb +0 -308
  154. data/test/plugin/test_out_exec.rb +0 -312
  155. data/test/plugin/test_out_exec_filter.rb +0 -606
  156. data/test/plugin/test_out_file.rb +0 -1038
  157. data/test/plugin/test_out_forward.rb +0 -1349
  158. data/test/plugin/test_out_http.rb +0 -557
  159. data/test/plugin/test_out_null.rb +0 -105
  160. data/test/plugin/test_out_relabel.rb +0 -28
  161. data/test/plugin/test_out_roundrobin.rb +0 -146
  162. data/test/plugin/test_out_secondary_file.rb +0 -458
  163. data/test/plugin/test_out_stdout.rb +0 -205
  164. data/test/plugin/test_out_stream.rb +0 -103
  165. data/test/plugin/test_output.rb +0 -1334
  166. data/test/plugin/test_output_as_buffered.rb +0 -2024
  167. data/test/plugin/test_output_as_buffered_backup.rb +0 -363
  168. data/test/plugin/test_output_as_buffered_compress.rb +0 -179
  169. data/test/plugin/test_output_as_buffered_overflow.rb +0 -250
  170. data/test/plugin/test_output_as_buffered_retries.rb +0 -966
  171. data/test/plugin/test_output_as_buffered_secondary.rb +0 -882
  172. data/test/plugin/test_output_as_standard.rb +0 -374
  173. data/test/plugin/test_owned_by.rb +0 -34
  174. data/test/plugin/test_parser.rb +0 -399
  175. data/test/plugin/test_parser_apache.rb +0 -42
  176. data/test/plugin/test_parser_apache2.rb +0 -47
  177. data/test/plugin/test_parser_apache_error.rb +0 -45
  178. data/test/plugin/test_parser_csv.rb +0 -200
  179. data/test/plugin/test_parser_json.rb +0 -244
  180. data/test/plugin/test_parser_labeled_tsv.rb +0 -160
  181. data/test/plugin/test_parser_msgpack.rb +0 -127
  182. data/test/plugin/test_parser_multiline.rb +0 -111
  183. data/test/plugin/test_parser_nginx.rb +0 -88
  184. data/test/plugin/test_parser_none.rb +0 -52
  185. data/test/plugin/test_parser_regexp.rb +0 -284
  186. data/test/plugin/test_parser_syslog.rb +0 -650
  187. data/test/plugin/test_parser_tsv.rb +0 -122
  188. data/test/plugin/test_sd_file.rb +0 -228
  189. data/test/plugin/test_sd_srv.rb +0 -230
  190. data/test/plugin/test_storage.rb +0 -166
  191. data/test/plugin/test_storage_local.rb +0 -335
  192. data/test/plugin/test_string_util.rb +0 -26
  193. data/test/plugin_helper/data/cert/cert-key.pem +0 -27
  194. data/test/plugin_helper/data/cert/cert-with-CRLF.pem +0 -19
  195. data/test/plugin_helper/data/cert/cert-with-no-newline.pem +0 -19
  196. data/test/plugin_helper/data/cert/cert.pem +0 -19
  197. data/test/plugin_helper/data/cert/cert_chains/ca-cert-key.pem +0 -27
  198. data/test/plugin_helper/data/cert/cert_chains/ca-cert.pem +0 -20
  199. data/test/plugin_helper/data/cert/cert_chains/cert-key.pem +0 -27
  200. data/test/plugin_helper/data/cert/cert_chains/cert.pem +0 -40
  201. data/test/plugin_helper/data/cert/empty.pem +0 -0
  202. data/test/plugin_helper/data/cert/generate_cert.rb +0 -125
  203. data/test/plugin_helper/data/cert/with_ca/ca-cert-key-pass.pem +0 -30
  204. data/test/plugin_helper/data/cert/with_ca/ca-cert-key.pem +0 -27
  205. data/test/plugin_helper/data/cert/with_ca/ca-cert-pass.pem +0 -20
  206. data/test/plugin_helper/data/cert/with_ca/ca-cert.pem +0 -20
  207. data/test/plugin_helper/data/cert/with_ca/cert-key-pass.pem +0 -30
  208. data/test/plugin_helper/data/cert/with_ca/cert-key.pem +0 -27
  209. data/test/plugin_helper/data/cert/with_ca/cert-pass.pem +0 -21
  210. data/test/plugin_helper/data/cert/with_ca/cert.pem +0 -21
  211. data/test/plugin_helper/data/cert/without_ca/cert-key-pass.pem +0 -30
  212. data/test/plugin_helper/data/cert/without_ca/cert-key.pem +0 -27
  213. data/test/plugin_helper/data/cert/without_ca/cert-pass.pem +0 -20
  214. data/test/plugin_helper/data/cert/without_ca/cert.pem +0 -20
  215. data/test/plugin_helper/http_server/test_app.rb +0 -65
  216. data/test/plugin_helper/http_server/test_route.rb +0 -32
  217. data/test/plugin_helper/service_discovery/test_manager.rb +0 -93
  218. data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +0 -21
  219. data/test/plugin_helper/test_cert_option.rb +0 -25
  220. data/test/plugin_helper/test_child_process.rb +0 -862
  221. data/test/plugin_helper/test_compat_parameters.rb +0 -358
  222. data/test/plugin_helper/test_event_emitter.rb +0 -80
  223. data/test/plugin_helper/test_event_loop.rb +0 -52
  224. data/test/plugin_helper/test_extract.rb +0 -194
  225. data/test/plugin_helper/test_formatter.rb +0 -255
  226. data/test/plugin_helper/test_http_server_helper.rb +0 -372
  227. data/test/plugin_helper/test_inject.rb +0 -561
  228. data/test/plugin_helper/test_metrics.rb +0 -137
  229. data/test/plugin_helper/test_parser.rb +0 -264
  230. data/test/plugin_helper/test_record_accessor.rb +0 -238
  231. data/test/plugin_helper/test_retry_state.rb +0 -1006
  232. data/test/plugin_helper/test_server.rb +0 -1895
  233. data/test/plugin_helper/test_service_discovery.rb +0 -165
  234. data/test/plugin_helper/test_socket.rb +0 -146
  235. data/test/plugin_helper/test_storage.rb +0 -542
  236. data/test/plugin_helper/test_thread.rb +0 -164
  237. data/test/plugin_helper/test_timer.rb +0 -130
  238. data/test/scripts/exec_script.rb +0 -32
  239. data/test/scripts/fluent/plugin/formatter1/formatter_test1.rb +0 -7
  240. data/test/scripts/fluent/plugin/formatter2/formatter_test2.rb +0 -7
  241. data/test/scripts/fluent/plugin/formatter_known.rb +0 -8
  242. data/test/scripts/fluent/plugin/out_test.rb +0 -81
  243. data/test/scripts/fluent/plugin/out_test2.rb +0 -80
  244. data/test/scripts/fluent/plugin/parser_known.rb +0 -4
  245. data/test/test_capability.rb +0 -74
  246. data/test/test_clock.rb +0 -164
  247. data/test/test_config.rb +0 -369
  248. data/test/test_configdsl.rb +0 -148
  249. data/test/test_daemonizer.rb +0 -91
  250. data/test/test_engine.rb +0 -203
  251. data/test/test_event.rb +0 -531
  252. data/test/test_event_router.rb +0 -348
  253. data/test/test_event_time.rb +0 -199
  254. data/test/test_file_wrapper.rb +0 -53
  255. data/test/test_filter.rb +0 -121
  256. data/test/test_fluent_log_event_router.rb +0 -99
  257. data/test/test_formatter.rb +0 -369
  258. data/test/test_input.rb +0 -31
  259. data/test/test_log.rb +0 -1076
  260. data/test/test_match.rb +0 -148
  261. data/test/test_mixin.rb +0 -351
  262. data/test/test_msgpack_factory.rb +0 -50
  263. data/test/test_oj_options.rb +0 -55
  264. data/test/test_output.rb +0 -278
  265. data/test/test_plugin.rb +0 -251
  266. data/test/test_plugin_classes.rb +0 -370
  267. data/test/test_plugin_helper.rb +0 -81
  268. data/test/test_plugin_id.rb +0 -119
  269. data/test/test_process.rb +0 -14
  270. data/test/test_root_agent.rb +0 -951
  271. data/test/test_static_config_analysis.rb +0 -177
  272. data/test/test_supervisor.rb +0 -821
  273. data/test/test_test_drivers.rb +0 -136
  274. data/test/test_time_formatter.rb +0 -301
  275. data/test/test_time_parser.rb +0 -362
  276. data/test/test_tls.rb +0 -65
  277. data/test/test_unique_id.rb +0 -47
  278. data/test/test_variable_store.rb +0 -65
@@ -1,1334 +0,0 @@
1
- require_relative '../helper'
2
- require 'fluent/plugin/output'
3
- require 'fluent/plugin/buffer'
4
- require 'fluent/event'
5
-
6
- require 'json'
7
- require 'time'
8
- require 'timeout'
9
-
10
- module FluentPluginOutputTest
11
- class DummyBareOutput < Fluent::Plugin::Output
12
- def register(name, &block)
13
- instance_variable_set("@#{name}", block)
14
- end
15
- end
16
- class DummySyncOutput < DummyBareOutput
17
- def initialize
18
- super
19
- @process = nil
20
- end
21
- def process(tag, es)
22
- @process ? @process.call(tag, es) : nil
23
- end
24
- end
25
- class DummyAsyncOutput < DummyBareOutput
26
- def initialize
27
- super
28
- @format = nil
29
- @write = nil
30
- end
31
- def format(tag, time, record)
32
- @format ? @format.call(tag, time, record) : [tag, time, record].to_json
33
- end
34
- def write(chunk)
35
- @write ? @write.call(chunk) : nil
36
- end
37
- end
38
- class DummyAsyncStandardOutput < DummyBareOutput
39
- def initialize
40
- super
41
- @write = nil
42
- end
43
- def write(chunk)
44
- @write ? @write.call(chunk) : nil
45
- end
46
- end
47
- class DummyDelayedOutput < DummyBareOutput
48
- def initialize
49
- super
50
- @format = nil
51
- @try_write = nil
52
- end
53
- def format(tag, time, record)
54
- @format ? @format.call(tag, time, record) : [tag, time, record].to_json
55
- end
56
- def try_write(chunk)
57
- @try_write ? @try_write.call(chunk) : nil
58
- end
59
- end
60
- class DummyDelayedStandardOutput < DummyBareOutput
61
- def initialize
62
- super
63
- @try_write = nil
64
- end
65
- def try_write(chunk)
66
- @try_write ? @try_write.call(chunk) : nil
67
- end
68
- end
69
- class DummyFullFeatureOutput < DummyBareOutput
70
- def initialize
71
- super
72
- @prefer_buffered_processing = nil
73
- @prefer_delayed_commit = nil
74
- @process = nil
75
- @format = nil
76
- @write = nil
77
- @try_write = nil
78
- end
79
- def prefer_buffered_processing
80
- @prefer_buffered_processing ? @prefer_buffered_processing.call : false
81
- end
82
- def prefer_delayed_commit
83
- @prefer_delayed_commit ? @prefer_delayed_commit.call : false
84
- end
85
- def process(tag, es)
86
- @process ? @process.call(tag, es) : nil
87
- end
88
- def format(tag, time, record)
89
- @format ? @format.call(tag, time, record) : [tag, time, record].to_json
90
- end
91
- def write(chunk)
92
- @write ? @write.call(chunk) : nil
93
- end
94
- def try_write(chunk)
95
- @try_write ? @try_write.call(chunk) : nil
96
- end
97
- end
98
- end
99
-
100
- class OutputTest < Test::Unit::TestCase
101
- class << self
102
- def startup
103
- $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../scripts'))
104
- require 'fluent/plugin/out_test'
105
- end
106
-
107
- def shutdown
108
- $LOAD_PATH.shift
109
- end
110
- end
111
-
112
- def create_output(type=:full)
113
- case type
114
- when :bare then FluentPluginOutputTest::DummyBareOutput.new
115
- when :sync then FluentPluginOutputTest::DummySyncOutput.new
116
- when :buffered then FluentPluginOutputTest::DummyAsyncOutput.new
117
- when :standard then FluentPluginOutputTest::DummyAsyncStandardOutput.new
118
- when :delayed then FluentPluginOutputTest::DummyDelayedOutput.new
119
- when :sdelayed then FluentPluginOutputTest::DummyDelayedStandardOutput.new
120
- when :full then FluentPluginOutputTest::DummyFullFeatureOutput.new
121
- else
122
- raise ArgumentError, "unknown type: #{type}"
123
- end
124
- end
125
- def create_metadata(timekey: nil, tag: nil, variables: nil)
126
- Fluent::Plugin::Buffer::Metadata.new(timekey, tag, variables)
127
- end
128
- def create_chunk(timekey: nil, tag: nil, variables: nil)
129
- m = Fluent::Plugin::Buffer::Metadata.new(timekey, tag, variables)
130
- Fluent::Plugin::Buffer::MemoryChunk.new(m)
131
- end
132
- def waiting(seconds)
133
- begin
134
- Timeout.timeout(seconds) do
135
- yield
136
- end
137
- rescue Timeout::Error
138
- STDERR.print(*@i.log.out.logs)
139
- raise
140
- end
141
- end
142
-
143
- sub_test_case 'basic output feature' do
144
- setup do
145
- @i = create_output(:full)
146
- end
147
-
148
- test 'are not available with multi workers configuration in default' do
149
- assert_false @i.multi_workers_ready?
150
- end
151
-
152
- test '#implement? can return features for plugin instances' do
153
- i1 = FluentPluginOutputTest::DummyBareOutput.new
154
- assert !i1.implement?(:synchronous)
155
- assert !i1.implement?(:buffered)
156
- assert !i1.implement?(:delayed_commit)
157
- assert !i1.implement?(:custom_format)
158
-
159
- i2 = FluentPluginOutputTest::DummySyncOutput.new
160
- assert i2.implement?(:synchronous)
161
- assert !i2.implement?(:buffered)
162
- assert !i2.implement?(:delayed_commit)
163
- assert !i2.implement?(:custom_format)
164
-
165
- i3 = FluentPluginOutputTest::DummyAsyncOutput.new
166
- assert !i3.implement?(:synchronous)
167
- assert i3.implement?(:buffered)
168
- assert !i3.implement?(:delayed_commit)
169
- assert i3.implement?(:custom_format)
170
-
171
- i4 = FluentPluginOutputTest::DummyAsyncStandardOutput.new
172
- assert !i4.implement?(:synchronous)
173
- assert i4.implement?(:buffered)
174
- assert !i4.implement?(:delayed_commit)
175
- assert !i4.implement?(:custom_format)
176
-
177
- i5 = FluentPluginOutputTest::DummyDelayedOutput.new
178
- assert !i5.implement?(:synchronous)
179
- assert !i5.implement?(:buffered)
180
- assert i5.implement?(:delayed_commit)
181
- assert i5.implement?(:custom_format)
182
-
183
- i6 = FluentPluginOutputTest::DummyDelayedStandardOutput.new
184
- assert !i6.implement?(:synchronous)
185
- assert !i6.implement?(:buffered)
186
- assert i6.implement?(:delayed_commit)
187
- assert !i6.implement?(:custom_format)
188
-
189
- i6 = FluentPluginOutputTest::DummyFullFeatureOutput.new
190
- assert i6.implement?(:synchronous)
191
- assert i6.implement?(:buffered)
192
- assert i6.implement?(:delayed_commit)
193
- assert i6.implement?(:custom_format)
194
- end
195
-
196
- test 'plugin lifecycle for configure/start/stop/before_shutdown/shutdown/after_shutdown/close/terminate' do
197
- assert !@i.configured?
198
- @i.configure(config_element())
199
- assert @i.configured?
200
- assert !@i.started?
201
- @i.start
202
- assert @i.started?
203
- assert !@i.after_started?
204
- @i.after_start
205
- assert @i.after_started?
206
- assert !@i.stopped?
207
- @i.stop
208
- assert @i.stopped?
209
- assert !@i.before_shutdown?
210
- @i.before_shutdown
211
- assert @i.before_shutdown?
212
- assert !@i.shutdown?
213
- @i.shutdown
214
- assert @i.shutdown?
215
- assert !@i.after_shutdown?
216
- @i.after_shutdown
217
- assert @i.after_shutdown?
218
- assert !@i.closed?
219
- @i.close
220
- assert @i.closed?
221
- assert !@i.terminated?
222
- @i.terminate
223
- assert @i.terminated?
224
- end
225
-
226
- test 'can use metrics plugins and fallback methods' do
227
- @i.configure(config_element())
228
-
229
- %w[num_errors_metrics emit_count_metrics emit_size_metrics emit_records_metrics
230
- write_count_metrics rollback_count_metrics flush_time_count_metrics slow_flush_count_metrics].each do |metric_name|
231
- assert_true @i.instance_variable_get(:"@#{metric_name}").is_a?(Fluent::Plugin::Metrics)
232
- end
233
-
234
- assert_equal 0, @i.num_errors
235
- assert_equal 0, @i.emit_count
236
- assert_equal 0, @i.emit_size
237
- assert_equal 0, @i.emit_records
238
- assert_equal 0, @i.write_count
239
- assert_equal 0, @i.rollback_count
240
- end
241
-
242
- data(:new_api => :chunk,
243
- :old_api => :metadata)
244
- test '#extract_placeholders does nothing if chunk key is not specified' do |api|
245
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
246
- assert !@i.chunk_key_time
247
- assert !@i.chunk_key_tag
248
- assert_equal [], @i.chunk_keys
249
- tmpl = "/mypath/%Y/%m/%d/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
250
- t = event_time('2016-04-11 20:30:00 +0900')
251
- v = {key1: "value1", key2: "value2"}
252
- c = if api == :chunk
253
- create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
254
- else
255
- create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
256
- end
257
- assert_equal tmpl, @i.extract_placeholders(tmpl, c)
258
- end
259
-
260
- data(:new_api => :chunk,
261
- :old_api => :metadata)
262
- test '#extract_placeholders can extract time if time key and range are configured' do |api|
263
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {'timekey' => 60*30, 'timekey_zone' => "+0900"})]))
264
- assert @i.chunk_key_time
265
- assert !@i.chunk_key_tag
266
- assert_equal [], @i.chunk_keys
267
- tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
268
- t = event_time('2016-04-11 20:30:00 +0900')
269
- v = {key1: "value1", key2: "value2"}
270
- c = if api == :chunk
271
- create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
272
- else
273
- create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
274
- end
275
- assert_equal "/mypath/2016/04/11/20-30/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail", @i.extract_placeholders(tmpl, c)
276
- end
277
-
278
- data(:new_api => :chunk,
279
- :old_api => :metadata)
280
- test '#extract_placeholders can extract tag and parts of tag if tag is configured' do |api|
281
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'tag', {})]))
282
- assert !@i.chunk_key_time
283
- assert @i.chunk_key_tag
284
- assert_equal [], @i.chunk_keys
285
- tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
286
- t = event_time('2016-04-11 20:30:00 +0900')
287
- v = {key1: "value1", key2: "value2"}
288
- c = if api == :chunk
289
- create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
290
- else
291
- create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
292
- end
293
- assert_equal "/mypath/%Y/%m/%d/%H-%M/fluentd.test.output/test/output/${key1}/${key2}/tail", @i.extract_placeholders(tmpl, c)
294
- end
295
-
296
- data(:new_api => :chunk,
297
- :old_api => :metadata)
298
- test '#extract_placeholders can extract variables if variables are configured' do |api|
299
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'key1,key2', {})]))
300
- assert !@i.chunk_key_time
301
- assert !@i.chunk_key_tag
302
- assert_equal ['key1','key2'], @i.chunk_keys
303
- tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
304
- t = event_time('2016-04-11 20:30:00 +0900')
305
- v = {key1: "value1", key2: "value2"}
306
- c = if api == :chunk
307
- create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
308
- else
309
- create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
310
- end
311
- assert_equal "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/value1/value2/tail", @i.extract_placeholders(tmpl, c)
312
- end
313
-
314
- data(:new_api => :chunk,
315
- :old_api => :metadata)
316
- test '#extract_placeholders can extract nested variables if variables are configured with dot notation' do |api|
317
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'key,$.nest.key', {})]))
318
- assert !@i.chunk_key_time
319
- assert !@i.chunk_key_tag
320
- assert_equal ['key','$.nest.key'], @i.chunk_keys
321
- tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key}/${$.nest.key}/tail"
322
- t = event_time('2016-04-11 20:30:00 +0900')
323
- v = {:key => "value1", :"$.nest.key" => "value2"}
324
- c = if api == :chunk
325
- create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
326
- else
327
- create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
328
- end
329
- assert_equal "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/value1/value2/tail", @i.extract_placeholders(tmpl, c)
330
- end
331
-
332
- data(:new_api => :chunk,
333
- :old_api => :metadata)
334
- test '#extract_placeholders can extract all chunk keys if configured' do |api|
335
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time,tag,key1,key2', {'timekey' => 60*30, 'timekey_zone' => "+0900"})]))
336
- assert @i.chunk_key_time
337
- assert @i.chunk_key_tag
338
- assert_equal ['key1','key2'], @i.chunk_keys
339
- tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[1]}/${tag[2]}/${key1}/${key2}/tail"
340
- t = event_time('2016-04-11 20:30:00 +0900')
341
- v = {key1: "value1", key2: "value2"}
342
- c = if api == :chunk
343
- create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
344
- else
345
- create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
346
- end
347
- assert_equal "/mypath/2016/04/11/20-30/fluentd.test.output/test/output/value1/value2/tail", @i.extract_placeholders(tmpl, c)
348
- end
349
-
350
- data(:new_api => :chunk,
351
- :old_api => :metadata)
352
- test '#extract_placeholders can extract negative index with tag' do |api|
353
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time,tag,key1,key2', {'timekey' => 60*30, 'timekey_zone' => "+0900"})]))
354
- assert @i.chunk_key_time
355
- assert @i.chunk_key_tag
356
- assert_equal ['key1','key2'], @i.chunk_keys
357
- tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[-1]}/${tag[-2]}/${key1}/${key2}/tail"
358
- t = event_time('2016-04-11 20:30:00 +0900')
359
- v = {key1: "value1", key2: "value2"}
360
- c = if api == :chunk
361
- create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
362
- else
363
- create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
364
- end
365
- assert_equal "/mypath/2016/04/11/20-30/fluentd.test.output/output/test/value1/value2/tail", @i.extract_placeholders(tmpl, c)
366
- end
367
-
368
- data(:new_api => :chunk,
369
- :old_api => :metadata)
370
- test '#extract_placeholders removes out-of-range tag part and unknown variable placeholders' do |api|
371
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time,tag,key1,key2', {'timekey' => 60*30, 'timekey_zone' => "+0900"})]))
372
- assert @i.chunk_key_time
373
- assert @i.chunk_key_tag
374
- assert_equal ['key1','key2'], @i.chunk_keys
375
- tmpl = "/mypath/%Y/%m/%d/%H-%M/${tag}/${tag[3]}/${tag[-4]}/${key3}/${key4}/tail"
376
- t = event_time('2016-04-11 20:30:00 +0900')
377
- v = {key1: "value1", key2: "value2"}
378
- c = if api == :chunk
379
- create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
380
- else
381
- create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
382
- end
383
- assert_equal "/mypath/2016/04/11/20-30/fluentd.test.output/////tail", @i.extract_placeholders(tmpl, c)
384
- end
385
-
386
- test '#extract_placeholders logs warn message if metadata is passed for ${chunk_id} placeholder' do
387
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
388
- tmpl = "/mypath/${chunk_id}/tail"
389
- t = event_time('2016-04-11 20:30:00 +0900')
390
- v = {key1: "value1", key2: "value2"}
391
- m = create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
392
- @i.extract_placeholders(tmpl, m)
393
- logs = @i.log.out.logs
394
- assert { logs.any? { |log| log.include?("${chunk_id} is not allowed in this plugin") } }
395
- end
396
-
397
- test '#extract_placeholders does not log for ${chunk_id} placeholder' do
398
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
399
- tmpl = "/mypath/${chunk_id}/tail"
400
- t = event_time('2016-04-11 20:30:00 +0900')
401
- v = {key1: "value1", key2: "value2"}
402
- c = create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
403
- @i.log.out.logs.clear
404
- @i.extract_placeholders(tmpl, c)
405
- logs = @i.log.out.logs
406
- assert { logs.none? { |log| log.include?("${chunk_id}") } }
407
- end
408
-
409
- test '#extract_placeholders does not log for ${chunk_id} placeholder (with @chunk_keys)' do
410
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'key1')]))
411
- tmpl = "/mypath/${chunk_id}/${key1}/tail"
412
- t = event_time('2016-04-11 20:30:00 +0900')
413
- v = {key1: "value1", key2: "value2"}
414
- c = create_chunk(timekey: t, tag: 'fluentd.test.output', variables: v)
415
- @i.log.out.logs.clear
416
- @i.extract_placeholders(tmpl, c)
417
- logs = @i.log.out.logs
418
- assert { logs.none? { |log| log.include?("${chunk_id}") } }
419
- end
420
-
421
- test '#extract_placeholders logs warn message with not replaced key' do
422
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
423
- tmpl = "/mypath/${key1}/test"
424
- t = event_time('2016-04-11 20:30:00 +0900')
425
- v = { key1: "value1" }
426
- m = create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
427
- @i.extract_placeholders(tmpl, m)
428
- logs = @i.log.out.logs
429
-
430
- assert { logs.any? { |log| log.include?("chunk key placeholder 'key1' not replaced. template:#{tmpl}") } }
431
- end
432
-
433
- test '#extract_placeholders logs warn message with not replaced key if variables exist and chunk_key is not empty' do
434
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'key1')]))
435
- tmpl = "/mypath/${key1}/${key2}/test"
436
- t = event_time('2016-04-11 20:30:00 +0900')
437
- v = { key1: "value1" }
438
- m = create_metadata(timekey: t, tag: 'fluentd.test.output', variables: v)
439
- @i.extract_placeholders(tmpl, m)
440
- logs = @i.log.out.logs
441
-
442
- assert { logs.any? { |log| log.include?("chunk key placeholder 'key2' not replaced. template:#{tmpl}") } }
443
- end
444
-
445
- sub_test_case '#placeholder_validators' do
446
- test 'returns validators for time, tag and keys when a template has placeholders even if plugin is not configured with these keys' do
447
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
448
- validators = @i.placeholder_validators(:path, "/my/path/${tag}/${username}/file.%Y%m%d_%H%M.log")
449
- assert_equal 3, validators.size
450
- assert_equal 1, validators.count(&:time?)
451
- assert_equal 1, validators.count(&:tag?)
452
- assert_equal 1, validators.count(&:keys?)
453
- end
454
-
455
- test 'returns validators for time, tag and keys when a plugin is configured with these keys even if a template does not have placeholders' do
456
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time,tag,username', {'timekey' => 60})]))
457
- validators = @i.placeholder_validators(:path, "/my/path/file.log")
458
- assert_equal 3, validators.size
459
- assert_equal 1, validators.count(&:time?)
460
- assert_equal 1, validators.count(&:tag?)
461
- assert_equal 1, validators.count(&:keys?)
462
- end
463
-
464
- test 'returns a validator for time if a template has timestamp placeholders' do
465
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
466
- validators = @i.placeholder_validators(:path, "/my/path/file.%Y-%m-%d.log")
467
- assert_equal 1, validators.size
468
- assert_equal 1, validators.count(&:time?)
469
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.%Y-%m-%d.log' has timestamp placeholders, but chunk key 'time' is not configured") do
470
- validators.first.validate!
471
- end
472
- end
473
-
474
- test 'returns a validator for time if a plugin is configured with time key' do
475
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {'timekey' => '30'})]))
476
- validators = @i.placeholder_validators(:path, "/my/path/to/file.log")
477
- assert_equal 1, validators.size
478
- assert_equal 1, validators.count(&:time?)
479
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/to/file.log' doesn't have timestamp placeholders for timekey 30") do
480
- validators.first.validate!
481
- end
482
- end
483
-
484
- test 'returns a validator for tag if a template has tag placeholders' do
485
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
486
- validators = @i.placeholder_validators(:path, "/my/path/${tag}/file.log")
487
- assert_equal 1, validators.size
488
- assert_equal 1, validators.count(&:tag?)
489
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${tag}/file.log' has tag placeholders, but chunk key 'tag' is not configured") do
490
- validators.first.validate!
491
- end
492
- end
493
-
494
- test 'returns a validator for tag if a plugin is configured with tag key' do
495
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'tag')]))
496
- validators = @i.placeholder_validators(:path, "/my/path/file.log")
497
- assert_equal 1, validators.size
498
- assert_equal 1, validators.count(&:tag?)
499
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have tag placeholder") do
500
- validators.first.validate!
501
- end
502
- end
503
-
504
- test 'returns a validator for variable keys if a template has variable placeholders' do
505
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
506
- validators = @i.placeholder_validators(:path, "/my/path/${username}/file.${group}.log")
507
- assert_equal 1, validators.size
508
- assert_equal 1, validators.count(&:keys?)
509
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${username}/file.${group}.log' has placeholders, but chunk keys doesn't have keys group,username") do
510
- validators.first.validate!
511
- end
512
- end
513
-
514
- test 'returns a validator for variable keys if a plugin is configured with variable keys' do
515
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'username,group')]))
516
- validators = @i.placeholder_validators(:path, "/my/path/file.log")
517
- assert_equal 1, validators.size
518
- assert_equal 1, validators.count(&:keys?)
519
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have enough placeholders for keys group,username") do
520
- validators.first.validate!
521
- end
522
- end
523
- end
524
-
525
- sub_test_case '#placeholder_validate!' do
526
- test 'raises configuration error for a template when timestamp placeholders exist but time key is missing' do
527
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
528
- assert_raise Fluent::ConfigError.new("Parameter 'path: /path/without/timestamp/file.%Y%m%d-%H%M.log' has timestamp placeholders, but chunk key 'time' is not configured") do
529
- @i.placeholder_validate!(:path, "/path/without/timestamp/file.%Y%m%d-%H%M.log")
530
- end
531
- end
532
-
533
- test 'raises configuration error for a template without timestamp placeholders when timekey is configured' do
534
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {"timekey" => 180})]))
535
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have timestamp placeholders for timekey 180") do
536
- @i.placeholder_validate!(:path, "/my/path/file.log")
537
- end
538
- assert_nothing_raised do
539
- @i.placeholder_validate!(:path, "/my/path/%Y%m%d/file.%H%M.log")
540
- end
541
- end
542
-
543
- test 'raises configuration error for a template with timestamp placeholders when plugin is configured more fine timekey' do
544
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {"timekey" => 180})]))
545
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.%Y%m%d_%H.log' doesn't have timestamp placeholder for hour('%H') for timekey 180") do
546
- @i.placeholder_validate!(:path, "/my/path/file.%Y%m%d_%H.log")
547
- end
548
- assert_nothing_raised do
549
- @i.placeholder_validate!(:path, "/my/path/file.%Y%m%d_%H%M.log")
550
- end
551
- end
552
-
553
- test 'raises configuration error for a template when tag placeholders exist but tag key is missing' do
554
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
555
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${tag}/file.${tag[2]}.log' has tag placeholders, but chunk key 'tag' is not configured") do
556
- @i.placeholder_validate!(:path, "/my/path/${tag}/file.${tag[2]}.log")
557
- end
558
- end
559
-
560
- test 'raises configuration error for a template without tag placeholders when tagkey is configured' do
561
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'tag')]))
562
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have tag placeholder") do
563
- @i.placeholder_validate!(:path, "/my/path/file.log")
564
- end
565
- assert_nothing_raised do
566
- @i.placeholder_validate!(:path, "/my/path/${tag}/file.${tag[2]}.log")
567
- end
568
- assert_nothing_raised do
569
- @i.placeholder_validate!(:path, "/my/path/${tag}/file.${tag[-1]}.log")
570
- end
571
- end
572
-
573
- test 'raises configuration error for a template when variable key placeholders exist but chunk keys are missing' do
574
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '')]))
575
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${service}/file.${username}.log' has placeholders, but chunk keys doesn't have keys service,username") do
576
- @i.placeholder_validate!(:path, "/my/path/${service}/file.${username}.log")
577
- end
578
- end
579
-
580
- test 'raises configuration error for a template without variable key placeholders when chunk keys are configured' do
581
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'username,service')]))
582
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.log' doesn't have enough placeholders for keys service,username") do
583
- @i.placeholder_validate!(:path, "/my/path/file.log")
584
- end
585
- assert_nothing_raised do
586
- @i.placeholder_validate!(:path, "/my/path/${service}/file.${username}.log")
587
- end
588
- end
589
-
590
- test 'raise configuration error for a template and configuration with keys mismatch' do
591
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'username,service')]))
592
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/file.${username}.log' doesn't have enough placeholders for keys service") do
593
- @i.placeholder_validate!(:path, "/my/path/file.${username}.log")
594
- end
595
- assert_raise Fluent::ConfigError.new("Parameter 'path: /my/path/${service}/file.log' doesn't have enough placeholders for keys username") do
596
- @i.placeholder_validate!(:path, "/my/path/${service}/file.log")
597
- end
598
- assert_nothing_raised do
599
- @i.placeholder_validate!(:path, "/my/path/${service}/file.${username}.log")
600
- end
601
- end
602
- end
603
-
604
- test '#get_placeholders_time returns seconds,title and example placeholder for a template' do
605
- s, t, e = @i.get_placeholders_time("/path/to/dir/yay")
606
- assert_nil s
607
- assert_nil t
608
- assert_nil e
609
-
610
- s, t, e = @i.get_placeholders_time("/path/to/%Y%m%d/yay")
611
- assert_equal 86400, s
612
- assert_equal :day, t
613
- assert_equal '%d', e
614
- s, t, e = @i.get_placeholders_time("my birthday! at %F")
615
- assert_equal 86400, s
616
- assert_equal :day, t
617
- assert_equal '%d', e
618
-
619
- s, t, e = @i.get_placeholders_time("myfile.%Y-%m-%d_%H.log")
620
- assert_equal 3600, s
621
- assert_equal :hour, t
622
- assert_equal '%H', e
623
-
624
- s, t, e = @i.get_placeholders_time("part-%Y%m%d-%H%M.ts")
625
- assert_equal 60, s
626
- assert_equal :minute, t
627
- assert_equal '%M', e
628
-
629
- s, t, e = @i.get_placeholders_time("my first data at %F %T %z")
630
- assert_equal 1, s
631
- assert_equal :second, t
632
- assert_equal '%S', e
633
- end
634
-
635
- test '#get_placeholders_tag returns a list of tag part position for a template' do
636
- assert_equal [], @i.get_placeholders_tag("db.table")
637
- assert_equal [], @i.get_placeholders_tag("db.table_${non_tag}")
638
- assert_equal [-1], @i.get_placeholders_tag("table_${tag}")
639
- assert_equal [0, 1], @i.get_placeholders_tag("db_${tag[0]}.table_${tag[1]}")
640
- assert_equal [-1, 0], @i.get_placeholders_tag("/treedir/${tag[0]}/${tag}")
641
- end
642
-
643
- test '#get_placeholders_keys returns a list of keys for a template' do
644
- assert_equal [], @i.get_placeholders_keys("/path/to/my/data/file.log")
645
- assert_equal [], @i.get_placeholders_keys("/path/to/my/${tag}/file.log")
646
- assert_equal ['key1', 'key2'], @i.get_placeholders_keys("/path/to/${key2}/${tag}/file.${key1}.log")
647
- assert_equal ['.hidden', '0001', '@timestamp', 'a_key', 'my-domain'], @i.get_placeholders_keys("http://${my-domain}/${.hidden}/${0001}/${a_key}?timestamp=${@timestamp}")
648
- end
649
-
650
- data('include space' => 'ke y',
651
- 'bracket notation' => "$['key']",
652
- 'invalid notation' => "$.ke y")
653
- test 'configure checks invalid chunk keys' do |chunk_keys|
654
- i = create_output(:buffered)
655
- assert_raise Fluent::ConfigError do
656
- i.configure(config_element('ROOT' , '', {}, [config_element('buffer', chunk_keys)]))
657
- end
658
- end
659
-
660
- test '#metadata returns object which contains tag/timekey/variables from records as specified in configuration' do
661
- tag = 'test.output'
662
- time = event_time('2016-04-12 15:31:23 -0700')
663
- timekey = event_time('2016-04-12 15:00:00 -0700')
664
- record = {"key1" => "value1", "num1" => 1, "message" => "my message", "nest" => {"key" => "nested value"}}
665
-
666
- i1 = create_output(:buffered)
667
- i1.configure(config_element('ROOT','',{},[config_element('buffer', '')]))
668
- assert_equal create_metadata(), i1.metadata(tag, time, record)
669
-
670
- i2 = create_output(:buffered)
671
- i2.configure(config_element('ROOT','',{},[config_element('buffer', 'tag')]))
672
- assert_equal create_metadata(tag: tag), i2.metadata(tag, time, record)
673
-
674
- i3 = create_output(:buffered)
675
- i3.configure(config_element('ROOT','',{},[config_element('buffer', 'time', {"timekey" => 3600, "timekey_zone" => "-0700"})]))
676
- assert_equal create_metadata(timekey: timekey), i3.metadata(tag, time, record)
677
-
678
- i4 = create_output(:buffered)
679
- i4.configure(config_element('ROOT','',{},[config_element('buffer', 'key1', {})]))
680
- assert_equal create_metadata(variables: {key1: "value1"}), i4.metadata(tag, time, record)
681
-
682
- i5 = create_output(:buffered)
683
- i5.configure(config_element('ROOT','',{},[config_element('buffer', 'key1,num1', {})]))
684
- assert_equal create_metadata(variables: {key1: "value1", num1: 1}), i5.metadata(tag, time, record)
685
-
686
- i6 = create_output(:buffered)
687
- i6.configure(config_element('ROOT','',{},[config_element('buffer', 'tag,time', {"timekey" => 3600, "timekey_zone" => "-0700"})]))
688
- assert_equal create_metadata(timekey: timekey, tag: tag), i6.metadata(tag, time, record)
689
-
690
- i7 = create_output(:buffered)
691
- i7.configure(config_element('ROOT','',{},[config_element('buffer', 'tag,num1', {"timekey" => 3600, "timekey_zone" => "-0700"})]))
692
- assert_equal create_metadata(tag: tag, variables: {num1: 1}), i7.metadata(tag, time, record)
693
-
694
- i8 = create_output(:buffered)
695
- i8.configure(config_element('ROOT','',{},[config_element('buffer', 'time,tag,key1', {"timekey" => 3600, "timekey_zone" => "-0700"})]))
696
- assert_equal create_metadata(timekey: timekey, tag: tag, variables: {key1: "value1"}), i8.metadata(tag, time, record)
697
-
698
- i9 = create_output(:buffered)
699
- i9.configure(config_element('ROOT','',{},[config_element('buffer', 'key1,$.nest.key', {})]))
700
- assert_equal create_metadata(variables: {:key1 => "value1", :"$.nest.key" => 'nested value'}), i9.metadata(tag, time, record)
701
- end
702
-
703
- test '#emit calls #process via #emit_sync for non-buffered output' do
704
- i = create_output(:sync)
705
- process_called = false
706
- i.register(:process){|tag, es| process_called = true }
707
- i.configure(config_element())
708
- i.start
709
- i.after_start
710
-
711
- t = event_time()
712
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
713
-
714
- assert process_called
715
-
716
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
717
- end
718
-
719
- test '#emit calls #format for buffered output' do
720
- i = create_output(:buffered)
721
- format_called_times = 0
722
- i.register(:format){|tag, time, record| format_called_times += 1; '' }
723
- i.configure(config_element())
724
- i.start
725
- i.after_start
726
-
727
- t = event_time()
728
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
729
-
730
- assert_equal 2, format_called_times
731
-
732
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
733
- end
734
-
735
- test '#prefer_buffered_processing (returns false) decides non-buffered without <buffer> section' do
736
- i = create_output(:full)
737
-
738
- process_called = false
739
- format_called_times = 0
740
- i.register(:process){|tag, es| process_called = true }
741
- i.register(:format){|tag, time, record| format_called_times += 1; '' }
742
-
743
- i.configure(config_element())
744
- i.register(:prefer_buffered_processing){ false } # delayed decision is possible to change after (output's) configure
745
- i.start
746
- i.after_start
747
-
748
- assert !i.prefer_buffered_processing
749
-
750
- t = event_time()
751
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
752
-
753
- waiting(4){ Thread.pass until process_called }
754
-
755
- assert process_called
756
- assert_equal 0, format_called_times
757
-
758
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
759
- end
760
-
761
- test '#prefer_buffered_processing (returns true) decides buffered without <buffer> section' do
762
- i = create_output(:full)
763
-
764
- process_called = false
765
- format_called_times = 0
766
- i.register(:process){|tag, es| process_called = true }
767
- i.register(:format){|tag, time, record| format_called_times += 1; '' }
768
-
769
- i.configure(config_element())
770
- i.register(:prefer_buffered_processing){ true } # delayed decision is possible to change after (output's) configure
771
- i.start
772
- i.after_start
773
-
774
- assert i.prefer_buffered_processing
775
-
776
- t = event_time()
777
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
778
-
779
- assert !process_called
780
- assert_equal 2, format_called_times
781
-
782
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
783
- end
784
-
785
- test 'output plugin will call #write for normal buffered plugin to flush buffer chunks' do
786
- i = create_output(:buffered)
787
- write_called = false
788
- i.register(:write){ |chunk| write_called = true }
789
-
790
- i.configure(config_element('ROOT', '', {}, [config_element('buffer', '', {"flush_mode" => "immediate"})]))
791
- i.start
792
- i.after_start
793
-
794
- t = event_time()
795
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
796
- i.force_flush
797
-
798
- waiting(4){ Thread.pass until write_called }
799
-
800
- assert write_called
801
-
802
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
803
- end
804
-
805
- test 'output plugin will call #try_write for plugin supports delayed commit only to flush buffer chunks' do
806
- tmp_dir = File.join(__dir__, '../tmp/test_output')
807
-
808
- i = create_output(:delayed)
809
- i.system_config_override(root_dir: tmp_dir) # Backup files are generated in `tmp_dir`.
810
- try_write_called = false
811
- i.register(:try_write){|chunk| try_write_called = true; commit_write(chunk.unique_id) }
812
-
813
- i.configure(config_element('ROOT', '', {}, [config_element('buffer', '', {"flush_mode" => "immediate"})]))
814
- i.start
815
- i.after_start
816
-
817
- t = event_time()
818
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
819
- i.force_flush
820
-
821
- waiting(4){ Thread.pass until try_write_called }
822
-
823
- assert try_write_called
824
-
825
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
826
- ensure
827
- FileUtils.rm_rf(tmp_dir)
828
- end
829
-
830
- test '#prefer_delayed_commit (returns false) decides delayed commit is disabled if both are implemented' do
831
- i = create_output(:full)
832
- write_called = false
833
- try_write_called = false
834
- i.register(:write){ |chunk| write_called = true }
835
- i.register(:try_write){|chunk| try_write_called = true; commit_write(chunk.unique_id) }
836
-
837
- i.configure(config_element('ROOT', '', {}, [config_element('buffer', '', {"flush_mode" => "immediate"})]))
838
- i.register(:prefer_delayed_commit){ false } # delayed decision is possible to change after (output's) configure
839
- i.start
840
- i.after_start
841
-
842
- assert !i.prefer_delayed_commit
843
-
844
- t = event_time()
845
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
846
- i.force_flush
847
-
848
- waiting(4){ Thread.pass until write_called || try_write_called }
849
-
850
- assert write_called
851
- assert !try_write_called
852
-
853
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
854
- end
855
-
856
- test '#prefer_delayed_commit (returns true) decides delayed commit is enabled if both are implemented' do
857
- tmp_dir = File.join(__dir__, '../tmp/test_output')
858
-
859
- i = create_output(:full)
860
- i.system_config_override(root_dir: tmp_dir) # Backup files are generated in `tmp_dir`.
861
- write_called = false
862
- try_write_called = false
863
- i.register(:write){ |chunk| write_called = true }
864
- i.register(:try_write){|chunk| try_write_called = true; commit_write(chunk.unique_id) }
865
-
866
- i.configure(config_element('ROOT', '', {}, [config_element('buffer', '', {"flush_mode" => "immediate"})]))
867
- i.register(:prefer_delayed_commit){ true } # delayed decision is possible to change after (output's) configure
868
- i.start
869
- i.after_start
870
-
871
- assert i.prefer_delayed_commit
872
-
873
- t = event_time()
874
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
875
- i.force_flush
876
-
877
- waiting(4){ Thread.pass until write_called || try_write_called }
878
-
879
- assert !write_called
880
- assert try_write_called
881
-
882
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
883
- ensure
884
- FileUtils.rm_rf(tmp_dir)
885
- end
886
-
887
- test 'flush_interval is ignored when flush_mode is not interval' do
888
- mock(@i.log).warn("'flush_interval' is ignored because default 'flush_mode' is not 'interval': 'lazy'")
889
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', 'time', {'timekey' => 60*30, 'flush_interval' => 10})]))
890
- end
891
-
892
- data(:lazy => 'lazy', :immediate => 'immediate')
893
- test 'flush_interval and non-interval flush_mode is exclusive ' do |mode|
894
- assert_raise Fluent::ConfigError.new("'flush_interval' can't be specified when 'flush_mode' is not 'interval' explicitly: '#{mode}'") do
895
- @i.configure(config_element('ROOT', '', {}, [config_element('buffer', '', {'flush_mode' => mode, 'flush_interval' => 10})]))
896
- end
897
- end
898
-
899
- test 'flush_mode is set to interval when flush_interval with v0.12 configuration is given' do
900
- mock(@i.log).info("'flush_interval' is configured at out side of <buffer>. 'flush_mode' is set to 'interval' to keep existing behaviour")
901
- @i.configure(config_element('ROOT', '', {'flush_interval' => 60}, []))
902
- assert_equal :interval, @i.instance_variable_get(:@flush_mode)
903
- end
904
-
905
- sub_test_case 'configure secondary' do
906
- test "Warn if primary type is different from secondary type and either primary or secondary has custom_format" do
907
- o = create_output(:buffered)
908
- mock(o.log).warn("Use different plugin for secondary. Check the plugin works with primary like secondary_file",
909
- primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput")
910
-
911
- o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'test', 'name' => "cool"})]))
912
- assert_not_nil o.instance_variable_get(:@secondary)
913
- end
914
-
915
- test "don't warn if primary type is the same as secondary type" do
916
- o = Fluent::Plugin::TestOutput.new
917
- mock(o.log).warn("Use different plugin for secondary. Check the plugin works with primary like secondary_file",
918
- primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput" ).never
919
-
920
- o.configure(config_element('ROOT','',{'name' => "cool2"},
921
- [config_element('secondary','',{'@type'=>'test', 'name' => "cool"}),
922
- config_element('buffer','',{'@type'=>'memory'})]
923
- ))
924
- assert_not_nil o.instance_variable_get(:@secondary)
925
- end
926
-
927
- test "don't warn if primary type is different from secondary type and both don't have custom_format" do
928
- o = create_output(:standard)
929
- mock(o.log).warn("Use different plugin for secondary. Check the plugin works with primary like secondary_file",
930
- primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput").never
931
-
932
- o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'test', 'name' => "cool"})]))
933
- assert_not_nil o.instance_variable_get(:@secondary)
934
- end
935
-
936
- test "raise configuration error if secondary type specifies non buffered output" do
937
- o = create_output(:standard)
938
- assert_raise Fluent::ConfigError do
939
- o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'copy'})]))
940
- end
941
- end
942
- end
943
- end
944
-
945
- test 'raises an error if timekey is less than equal 0' do
946
- i = create_output(:delayed)
947
- assert_raise Fluent::ConfigError.new("<buffer ...> argument includes 'time', but timekey is not configured") do
948
- i.configure(config_element('ROOT','',{},[config_element('buffer', 'time', { "timekey" => nil })]))
949
- end
950
-
951
- i = create_output(:delayed)
952
- assert_raise Fluent::ConfigError.new('timekey should be greater than 0. current timekey: 0.0') do
953
- i.configure(config_element('ROOT','',{},[config_element('buffer', 'time', { "timekey" => 0 })]))
954
- end
955
-
956
- i = create_output(:delayed)
957
- assert_raise Fluent::ConfigError.new('timekey should be greater than 0. current timekey: -1.0') do
958
- i.configure(config_element('ROOT','',{},[config_element('buffer', 'time', { "timekey" => -1 })]))
959
- end
960
- end
961
-
962
- sub_test_case 'sync output feature' do
963
- setup do
964
- @i = create_output(:sync)
965
- end
966
-
967
- test 'raises configuration error if <buffer> section is specified' do
968
- assert_raise Fluent::ConfigError do
969
- @i.configure(config_element('ROOT','',{},[config_element('buffer', '')]))
970
- end
971
- end
972
-
973
- test 'raises configuration error if <secondary> section is specified' do
974
- assert_raise Fluent::ConfigError do
975
- @i.configure(config_element('ROOT','',{},[config_element('secondary','')]))
976
- end
977
- end
978
-
979
- test '#process is called for each event streams' do
980
- ary = []
981
- @i.register(:process){|tag, es| ary << [tag, es] }
982
- @i.configure(config_element())
983
- @i.start
984
- @i.after_start
985
-
986
- t = event_time()
987
- es = Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ])
988
- 5.times do
989
- @i.emit_events('tag', es)
990
- end
991
- assert_equal 5, ary.size
992
-
993
- @i.stop; @i.before_shutdown; @i.shutdown; @i.after_shutdown; @i.close; @i.terminate
994
- end
995
- end
996
-
997
- sub_test_case '#generate_format_proc' do
998
- test "when output doesn't have <buffer>" do
999
- i = create_output(:sync)
1000
- i.configure(config_element('ROOT', '', {}, []))
1001
- assert_equal Fluent::Plugin::Output::FORMAT_MSGPACK_STREAM, i.generate_format_proc
1002
- end
1003
-
1004
- test "when output doesn't have <buffer> and time_as_integer is true" do
1005
- i = create_output(:sync)
1006
- i.configure(config_element('ROOT', '', {'time_as_integer' => true}))
1007
- assert_equal Fluent::Plugin::Output::FORMAT_MSGPACK_STREAM_TIME_INT, i.generate_format_proc
1008
- end
1009
-
1010
- test 'when output has <buffer> and compress is gzip' do
1011
- i = create_output(:buffered)
1012
- i.configure(config_element('ROOT', '', {}, [config_element('buffer', '', {'compress' => 'gzip'})]))
1013
- assert_equal Fluent::Plugin::Output::FORMAT_COMPRESSED_MSGPACK_STREAM, i.generate_format_proc
1014
- end
1015
-
1016
- test 'when output has <buffer> and compress is gzip and time_as_integer is true' do
1017
- i = create_output(:buffered)
1018
- i.configure(config_element('ROOT', '', {'time_as_integer' => true}, [config_element('buffer', '', {'compress' => 'gzip'})]))
1019
- assert_equal Fluent::Plugin::Output::FORMAT_COMPRESSED_MSGPACK_STREAM_TIME_INT, i.generate_format_proc
1020
- end
1021
-
1022
- test 'when output has <buffer> and compress is text' do
1023
- i = create_output(:buffered)
1024
- i.configure(config_element('ROOT', '', {}, [config_element('buffer', '', {'compress' => 'text'})]))
1025
- assert_equal Fluent::Plugin::Output::FORMAT_MSGPACK_STREAM, i.generate_format_proc
1026
- end
1027
- end
1028
-
1029
- sub_test_case 'slow_flush_log_threshold' do
1030
- def invoke_slow_flush_log_threshold_test(i)
1031
- i.configure(config_element('ROOT', '', {'slow_flush_log_threshold' => 0.5},
1032
- [config_element('buffer', '', {"flush_mode" => "immediate", "flush_thread_interval" => 30})]))
1033
- i.start
1034
- i.after_start
1035
-
1036
- t = event_time()
1037
- i.emit_events('tag', Fluent::ArrayEventStream.new([ [t, {"key" => "value1"}], [t, {"key" => "value2"}] ]))
1038
- i.force_flush
1039
-
1040
- waiting(4) { Thread.pass until i.test_finished? }
1041
-
1042
- yield
1043
- ensure
1044
- i.stop; i.before_shutdown; i.shutdown; i.after_shutdown; i.close; i.terminate
1045
- end
1046
-
1047
- test '#write flush took longer time than slow_flush_log_threshold' do
1048
- i = create_output(:buffered)
1049
- write_called = false
1050
- i.register(:write) { |chunk| sleep 3 }
1051
- i.define_singleton_method(:test_finished?) { write_called }
1052
- i.define_singleton_method(:try_flush) { super(); write_called = true }
1053
-
1054
- invoke_slow_flush_log_threshold_test(i) {
1055
- assert write_called
1056
- logs = i.log.out.logs
1057
- assert{ logs.any?{|log| log.include?("buffer flush took longer time than slow_flush_log_threshold: elapsed_time") } }
1058
- }
1059
- end
1060
-
1061
- test '#try_write flush took longer time than slow_flush_log_threshold' do
1062
- i = create_output(:delayed)
1063
- try_write_called = false
1064
- i.register(:try_write){ |chunk| sleep 3 }
1065
- i.define_singleton_method(:test_finished?) { try_write_called }
1066
- i.define_singleton_method(:try_flush) { super(); try_write_called = true }
1067
-
1068
- invoke_slow_flush_log_threshold_test(i) {
1069
- assert try_write_called
1070
- logs = i.log.out.logs
1071
- assert{ logs.any?{|log| log.include?("buffer flush took longer time than slow_flush_log_threshold: elapsed_time") } }
1072
- }
1073
- end
1074
- end
1075
-
1076
- sub_test_case "actual_flush_thread_count" do
1077
- data(
1078
- "Not buffered",
1079
- {
1080
- output_type: :sync,
1081
- config: config_element(),
1082
- expected: 0,
1083
- }
1084
- )
1085
- data(
1086
- "Buffered with singile thread",
1087
- {
1088
- output_type: :full,
1089
- config: config_element("ROOT", "", {}, [config_element("buffer", "", {})]),
1090
- expected: 1,
1091
- }
1092
- )
1093
- data(
1094
- "Buffered with multiple threads",
1095
- {
1096
- output_type: :full,
1097
- config: config_element("ROOT", "", {}, [config_element("buffer", "", {"flush_thread_count" => 8})]),
1098
- expected: 8,
1099
- }
1100
- )
1101
- test "actual_flush_thread_count" do |data|
1102
- o = create_output(data[:output_type])
1103
- o.configure(data[:config])
1104
- assert_equal data[:expected], o.actual_flush_thread_count
1105
- end
1106
-
1107
- data(
1108
- "Buffered with single thread",
1109
- {
1110
- output_type: :full,
1111
- config: config_element(
1112
- "ROOT", "", {},
1113
- [
1114
- config_element("buffer", "", {}),
1115
- config_element("secondary", "", {"@type" => "test", "name" => "test"}),
1116
- ]
1117
- ),
1118
- expected: 1,
1119
- }
1120
- )
1121
- data(
1122
- "Buffered with multiple threads",
1123
- {
1124
- output_type: :full,
1125
- config: config_element(
1126
- "ROOT", "", {},
1127
- [
1128
- config_element("buffer", "", {"flush_thread_count" => 8}),
1129
- config_element("secondary", "", {"@type" => "test", "name" => "test"}),
1130
- ]
1131
- ),
1132
- expected: 8,
1133
- }
1134
- )
1135
- test "actual_flush_thread_count for secondary" do |data|
1136
- primary = create_output(data[:output_type])
1137
- primary.configure(data[:config])
1138
- assert_equal data[:expected], primary.secondary.actual_flush_thread_count
1139
- end
1140
- end
1141
-
1142
- sub_test_case "synchronize_path" do
1143
- def setup
1144
- Dir.mktmpdir do |lock_dir|
1145
- ENV['FLUENTD_LOCK_DIR'] = lock_dir
1146
- yield
1147
- end
1148
- end
1149
-
1150
- def assert_worker_lock(lock_path, expect_locked)
1151
- # With LOCK_NB set, flock() returns:
1152
- # * `false` when the file is already locked.
1153
- # * `0` when the file is not locked.
1154
- File.open(lock_path, "w") do |f|
1155
- if expect_locked
1156
- assert_equal false, f.flock(File::LOCK_EX|File::LOCK_NB)
1157
- else
1158
- assert_equal 0, f.flock(File::LOCK_EX|File::LOCK_NB)
1159
- end
1160
- end
1161
- end
1162
-
1163
- def assert_thread_lock(output_plugin, expect_locked)
1164
- t = Thread.new do
1165
- output_plugin.synchronize_path("test") do
1166
- end
1167
- end
1168
- if expect_locked
1169
- assert_nil t.join(3)
1170
- else
1171
- assert_not_nil t.join(3)
1172
- end
1173
- end
1174
-
1175
- data(
1176
- "Not buffered with single worker",
1177
- {
1178
- output_type: :sync,
1179
- config: config_element(),
1180
- workers: 1,
1181
- expect_worker_lock: false,
1182
- expect_thread_lock: false,
1183
- }
1184
- )
1185
- data(
1186
- "Not buffered with multiple workers",
1187
- {
1188
- output_type: :sync,
1189
- config: config_element(),
1190
- workers: 4,
1191
- expect_worker_lock: true,
1192
- expect_thread_lock: false,
1193
- }
1194
- )
1195
- data(
1196
- "Buffered with single thread and single worker",
1197
- {
1198
- output_type: :full,
1199
- config: config_element("ROOT", "", {}, [config_element("buffer", "", {})]),
1200
- workers: 1,
1201
- expect_worker_lock: false,
1202
- expect_thread_lock: false,
1203
- }
1204
- )
1205
- data(
1206
- "Buffered with multiple threads and single worker",
1207
- {
1208
- output_type: :full,
1209
- config: config_element("ROOT", "", {}, [config_element("buffer", "", {"flush_thread_count" => 8})]),
1210
- workers: 1,
1211
- expect_worker_lock: false,
1212
- expect_thread_lock: true,
1213
- }
1214
- )
1215
- data(
1216
- "Buffered with single thread and multiple workers",
1217
- {
1218
- output_type: :full,
1219
- config: config_element("ROOT", "", {}, [config_element("buffer", "", {})]),
1220
- workers: 4,
1221
- expect_worker_lock: true,
1222
- expect_thread_lock: false,
1223
- }
1224
- )
1225
- data(
1226
- "Buffered with multiple threads and multiple workers",
1227
- {
1228
- output_type: :full,
1229
- config: config_element("ROOT", "", {}, [config_element("buffer", "", {"flush_thread_count" => 8})]),
1230
- workers: 4,
1231
- expect_worker_lock: true,
1232
- expect_thread_lock: true,
1233
- }
1234
- )
1235
- test "synchronize_path" do |data|
1236
- o = create_output(data[:output_type])
1237
- o.configure(data[:config])
1238
- o.system_config_override(workers: data[:workers])
1239
-
1240
- test_lock_name = "test_lock_name"
1241
- lock_path = o.get_lock_path(test_lock_name)
1242
-
1243
- o.synchronize_path(test_lock_name) do
1244
- assert_worker_lock(lock_path, data[:expect_worker_lock])
1245
- assert_thread_lock(o, data[:expect_thread_lock])
1246
- end
1247
-
1248
- assert_worker_lock(lock_path, false)
1249
- assert_thread_lock(o, false)
1250
- end
1251
-
1252
- data(
1253
- "Buffered with single thread and single worker",
1254
- {
1255
- output_type: :full,
1256
- config: config_element(
1257
- "ROOT", "", {},
1258
- [
1259
- config_element("buffer", "", {}),
1260
- config_element("secondary", "", {"@type" => "test", "name" => "test"}),
1261
- ]
1262
- ),
1263
- workers: 1,
1264
- expect_worker_lock: false,
1265
- expect_thread_lock: false,
1266
- }
1267
- )
1268
- data(
1269
- "Buffered with multiple threads and single worker",
1270
- {
1271
- output_type: :full,
1272
- config: config_element(
1273
- "ROOT", "", {},
1274
- [
1275
- config_element("buffer", "", {"flush_thread_count" => 8}),
1276
- config_element("secondary", "", {"@type" => "test", "name" => "test"}),
1277
- ]
1278
- ),
1279
- workers: 1,
1280
- expect_worker_lock: false,
1281
- expect_thread_lock: true,
1282
- }
1283
- )
1284
- data(
1285
- "Buffered with single thread and multiple workers",
1286
- {
1287
- output_type: :full,
1288
- config: config_element(
1289
- "ROOT", "", {},
1290
- [
1291
- config_element("buffer", "", {}),
1292
- config_element("secondary", "", {"@type" => "test", "name" => "test"}),
1293
- ]
1294
- ),
1295
- workers: 4,
1296
- expect_worker_lock: true,
1297
- expect_thread_lock: false,
1298
- }
1299
- )
1300
- data(
1301
- "Buffered with multiple threads and multiple workers",
1302
- {
1303
- output_type: :full,
1304
- config: config_element(
1305
- "ROOT", "", {},
1306
- [
1307
- config_element("buffer", "", {"flush_thread_count" => 8}),
1308
- config_element("secondary", "", {"@type" => "test", "name" => "test"}),
1309
- ]
1310
- ),
1311
- workers: 4,
1312
- expect_worker_lock: true,
1313
- expect_thread_lock: true,
1314
- }
1315
- )
1316
- test "synchronize_path for secondary" do |data|
1317
- primary = create_output(data[:output_type])
1318
- primary.configure(data[:config])
1319
- secondary = primary.secondary
1320
- secondary.system_config_override(workers: data[:workers])
1321
-
1322
- test_lock_name = "test_lock_name"
1323
- lock_path = secondary.get_lock_path(test_lock_name)
1324
-
1325
- secondary.synchronize_path(test_lock_name) do
1326
- assert_worker_lock(lock_path, data[:expect_worker_lock])
1327
- assert_thread_lock(secondary, data[:expect_thread_lock])
1328
- end
1329
-
1330
- assert_worker_lock(lock_path, false)
1331
- assert_thread_lock(secondary, false)
1332
- end
1333
- end
1334
- end