fluentd 1.13.3 → 1.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/{bug_report.yaml → bug_report.yml} +2 -0
  3. data/.github/ISSUE_TEMPLATE/config.yml +2 -2
  4. data/.github/ISSUE_TEMPLATE/{feature_request.yaml → feature_request.yml} +1 -0
  5. data/.github/workflows/stale-actions.yml +11 -9
  6. data/.github/workflows/test.yml +32 -0
  7. data/CHANGELOG.md +490 -10
  8. data/CONTRIBUTING.md +2 -2
  9. data/MAINTAINERS.md +7 -5
  10. data/README.md +3 -23
  11. data/Rakefile +1 -1
  12. data/SECURITY.md +14 -0
  13. data/fluentd.gemspec +7 -8
  14. data/lib/fluent/command/cat.rb +13 -3
  15. data/lib/fluent/command/ctl.rb +6 -3
  16. data/lib/fluent/command/fluentd.rb +73 -65
  17. data/lib/fluent/command/plugin_config_formatter.rb +1 -1
  18. data/lib/fluent/compat/output.rb +9 -6
  19. data/lib/fluent/config/dsl.rb +1 -1
  20. data/lib/fluent/config/error.rb +12 -0
  21. data/lib/fluent/config/literal_parser.rb +2 -2
  22. data/lib/fluent/config/parser.rb +1 -1
  23. data/lib/fluent/config/v1_parser.rb +3 -3
  24. data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
  25. data/lib/fluent/config/yaml_parser/loader.rb +108 -0
  26. data/lib/fluent/config/yaml_parser/parser.rb +166 -0
  27. data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
  28. data/lib/fluent/config/yaml_parser.rb +56 -0
  29. data/lib/fluent/config.rb +14 -1
  30. data/lib/fluent/counter/server.rb +1 -1
  31. data/lib/fluent/counter/validator.rb +3 -3
  32. data/lib/fluent/daemon.rb +2 -4
  33. data/lib/fluent/engine.rb +1 -1
  34. data/lib/fluent/env.rb +4 -0
  35. data/lib/fluent/error.rb +3 -0
  36. data/lib/fluent/event.rb +8 -4
  37. data/lib/fluent/event_router.rb +47 -2
  38. data/lib/fluent/file_wrapper.rb +137 -0
  39. data/lib/fluent/log/console_adapter.rb +66 -0
  40. data/lib/fluent/log.rb +44 -5
  41. data/lib/fluent/match.rb +1 -1
  42. data/lib/fluent/msgpack_factory.rb +6 -1
  43. data/lib/fluent/oj_options.rb +1 -2
  44. data/lib/fluent/plugin/bare_output.rb +49 -8
  45. data/lib/fluent/plugin/base.rb +26 -9
  46. data/lib/fluent/plugin/buf_file.rb +34 -5
  47. data/lib/fluent/plugin/buf_file_single.rb +32 -3
  48. data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
  49. data/lib/fluent/plugin/buffer.rb +216 -70
  50. data/lib/fluent/plugin/filter.rb +35 -1
  51. data/lib/fluent/plugin/filter_record_transformer.rb +1 -1
  52. data/lib/fluent/plugin/in_forward.rb +2 -2
  53. data/lib/fluent/plugin/in_http.rb +39 -10
  54. data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
  55. data/lib/fluent/plugin/in_sample.rb +1 -1
  56. data/lib/fluent/plugin/in_syslog.rb +13 -1
  57. data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
  58. data/lib/fluent/plugin/in_tail/position_file.rb +33 -33
  59. data/lib/fluent/plugin/in_tail.rb +216 -84
  60. data/lib/fluent/plugin/in_tcp.rb +47 -2
  61. data/lib/fluent/plugin/input.rb +39 -1
  62. data/lib/fluent/plugin/metrics.rb +119 -0
  63. data/lib/fluent/plugin/metrics_local.rb +96 -0
  64. data/lib/fluent/plugin/multi_output.rb +43 -6
  65. data/lib/fluent/plugin/out_copy.rb +1 -1
  66. data/lib/fluent/plugin/out_exec_filter.rb +2 -2
  67. data/lib/fluent/plugin/out_file.rb +20 -2
  68. data/lib/fluent/plugin/out_forward/ack_handler.rb +19 -4
  69. data/lib/fluent/plugin/out_forward/socket_cache.rb +2 -0
  70. data/lib/fluent/plugin/out_forward.rb +17 -9
  71. data/lib/fluent/plugin/out_secondary_file.rb +39 -22
  72. data/lib/fluent/plugin/output.rb +167 -78
  73. data/lib/fluent/plugin/parser.rb +3 -4
  74. data/lib/fluent/plugin/parser_apache2.rb +1 -1
  75. data/lib/fluent/plugin/parser_json.rb +1 -1
  76. data/lib/fluent/plugin/parser_syslog.rb +1 -1
  77. data/lib/fluent/plugin/storage_local.rb +3 -5
  78. data/lib/fluent/plugin.rb +10 -1
  79. data/lib/fluent/plugin_helper/child_process.rb +3 -0
  80. data/lib/fluent/plugin_helper/event_emitter.rb +8 -1
  81. data/lib/fluent/plugin_helper/event_loop.rb +2 -2
  82. data/lib/fluent/plugin_helper/http_server/server.rb +2 -1
  83. data/lib/fluent/plugin_helper/metrics.rb +129 -0
  84. data/lib/fluent/plugin_helper/record_accessor.rb +1 -1
  85. data/lib/fluent/plugin_helper/retry_state.rb +14 -4
  86. data/lib/fluent/plugin_helper/server.rb +35 -6
  87. data/lib/fluent/plugin_helper/service_discovery.rb +2 -2
  88. data/lib/fluent/plugin_helper/socket.rb +13 -2
  89. data/lib/fluent/plugin_helper/thread.rb +3 -3
  90. data/lib/fluent/plugin_helper.rb +1 -0
  91. data/lib/fluent/plugin_id.rb +3 -2
  92. data/lib/fluent/registry.rb +2 -1
  93. data/lib/fluent/root_agent.rb +6 -0
  94. data/lib/fluent/rpc.rb +4 -3
  95. data/lib/fluent/supervisor.rb +283 -259
  96. data/lib/fluent/system_config.rb +13 -3
  97. data/lib/fluent/test/driver/base.rb +11 -5
  98. data/lib/fluent/test/driver/filter.rb +4 -0
  99. data/lib/fluent/test/startup_shutdown.rb +6 -8
  100. data/lib/fluent/time.rb +21 -20
  101. data/lib/fluent/version.rb +1 -1
  102. data/lib/fluent/win32api.rb +38 -0
  103. data/lib/fluent/winsvc.rb +5 -8
  104. data/templates/new_gem/test/helper.rb.erb +0 -1
  105. data/test/command/test_cat.rb +31 -2
  106. data/test/command/test_ctl.rb +1 -2
  107. data/test/command/test_fluentd.rb +209 -24
  108. data/test/command/test_plugin_config_formatter.rb +0 -1
  109. data/test/compat/test_parser.rb +6 -6
  110. data/test/config/test_system_config.rb +13 -11
  111. data/test/config/test_types.rb +1 -1
  112. data/test/log/test_console_adapter.rb +110 -0
  113. data/test/plugin/in_tail/test_io_handler.rb +26 -8
  114. data/test/plugin/in_tail/test_position_file.rb +48 -59
  115. data/test/plugin/out_forward/test_ack_handler.rb +39 -0
  116. data/test/plugin/out_forward/test_socket_cache.rb +26 -1
  117. data/test/plugin/test_bare_output.rb +14 -1
  118. data/test/plugin/test_base.rb +133 -1
  119. data/test/plugin/test_buf_file.rb +62 -23
  120. data/test/plugin/test_buf_file_single.rb +65 -0
  121. data/test/plugin/test_buffer.rb +267 -3
  122. data/test/plugin/test_buffer_chunk.rb +11 -0
  123. data/test/plugin/test_filter.rb +12 -1
  124. data/test/plugin/test_filter_parser.rb +1 -1
  125. data/test/plugin/test_filter_stdout.rb +2 -2
  126. data/test/plugin/test_in_forward.rb +9 -11
  127. data/test/plugin/test_in_http.rb +65 -3
  128. data/test/plugin/test_in_monitor_agent.rb +216 -11
  129. data/test/plugin/test_in_object_space.rb +9 -3
  130. data/test/plugin/test_in_syslog.rb +35 -0
  131. data/test/plugin/test_in_tail.rb +1393 -385
  132. data/test/plugin/test_in_tcp.rb +87 -2
  133. data/test/plugin/test_in_udp.rb +28 -0
  134. data/test/plugin/test_in_unix.rb +2 -2
  135. data/test/plugin/test_input.rb +12 -1
  136. data/test/plugin/test_metrics.rb +294 -0
  137. data/test/plugin/test_metrics_local.rb +96 -0
  138. data/test/plugin/test_multi_output.rb +25 -1
  139. data/test/plugin/test_out_exec.rb +6 -4
  140. data/test/plugin/test_out_exec_filter.rb +6 -2
  141. data/test/plugin/test_out_file.rb +34 -17
  142. data/test/plugin/test_out_forward.rb +78 -77
  143. data/test/plugin/test_out_http.rb +1 -0
  144. data/test/plugin/test_out_stdout.rb +2 -2
  145. data/test/plugin/test_output.rb +297 -12
  146. data/test/plugin/test_output_as_buffered.rb +44 -44
  147. data/test/plugin/test_output_as_buffered_compress.rb +32 -18
  148. data/test/plugin/test_output_as_buffered_retries.rb +54 -7
  149. data/test/plugin/test_output_as_buffered_secondary.rb +4 -4
  150. data/test/plugin/test_parser_regexp.rb +1 -6
  151. data/test/plugin/test_parser_syslog.rb +1 -1
  152. data/test/plugin_helper/test_cert_option.rb +1 -1
  153. data/test/plugin_helper/test_child_process.rb +38 -16
  154. data/test/plugin_helper/test_event_emitter.rb +29 -0
  155. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  156. data/test/plugin_helper/test_metrics.rb +137 -0
  157. data/test/plugin_helper/test_retry_state.rb +602 -38
  158. data/test/plugin_helper/test_server.rb +78 -6
  159. data/test/plugin_helper/test_timer.rb +2 -2
  160. data/test/test_config.rb +191 -24
  161. data/test/test_event_router.rb +17 -0
  162. data/test/test_file_wrapper.rb +53 -0
  163. data/test/test_formatter.rb +24 -21
  164. data/test/test_log.rb +122 -40
  165. data/test/test_msgpack_factory.rb +32 -0
  166. data/test/test_plugin_classes.rb +102 -0
  167. data/test/test_root_agent.rb +30 -1
  168. data/test/test_supervisor.rb +477 -257
  169. data/test/test_time_parser.rb +22 -0
  170. metadata +55 -34
  171. data/.drone.yml +0 -35
  172. data/.github/workflows/issue-auto-closer.yml +0 -12
  173. data/.github/workflows/linux-test.yaml +0 -36
  174. data/.github/workflows/macos-test.yaml +0 -30
  175. data/.github/workflows/windows-test.yaml +0 -46
  176. data/.gitlab-ci.yml +0 -103
  177. data/lib/fluent/plugin/file_wrapper.rb +0 -187
  178. data/test/plugin/test_file_wrapper.rb +0 -126
  179. data/test/test_logger_initializer.rb +0 -46
@@ -2,12 +2,15 @@ require_relative 'helper'
2
2
  require 'fluent/event_router'
3
3
  require 'fluent/system_config'
4
4
  require 'fluent/supervisor'
5
+ require 'fluent/file_wrapper'
5
6
  require_relative 'test_plugin_classes'
6
7
 
7
8
  require 'net/http'
8
9
  require 'uri'
9
10
  require 'fileutils'
10
11
  require 'tempfile'
12
+ require 'securerandom'
13
+ require 'pathname'
11
14
 
12
15
  if Fluent.windows?
13
16
  require 'win32/event'
@@ -22,33 +25,47 @@ class SupervisorTest < ::Test::Unit::TestCase
22
25
  end
23
26
  end
24
27
 
25
- TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/tmp/supervisor#{ENV['TEST_ENV_NUMBER']}")
26
- TMP_ROOT_DIR = File.join(TMP_DIR, 'root')
28
+ def tmp_dir
29
+ File.join(File.dirname(__FILE__), "tmp", "supervisor#{ENV['TEST_ENV_NUMBER']}", SecureRandom.hex(10))
30
+ end
27
31
 
28
32
  def setup
29
- FileUtils.rm_rf(TMP_DIR)
30
- FileUtils.mkdir_p(TMP_DIR)
33
+ @stored_global_logger = $log
34
+ @tmp_dir = tmp_dir
35
+ @tmp_root_dir = File.join(@tmp_dir, 'root')
36
+ FileUtils.mkdir_p(@tmp_dir)
37
+ @sigdump_path = "/tmp/sigdump-#{Process.pid}.log"
38
+ end
39
+
40
+ def teardown
41
+ $log = @stored_global_logger
42
+ begin
43
+ FileUtils.rm_rf(@tmp_dir)
44
+ rescue Errno::EACCES
45
+ # It may occur on Windows because of delete pending state due to delayed GC.
46
+ # Ruby 3.2 or later doesn't ignore Errno::EACCES:
47
+ # https://github.com/ruby/ruby/commit/983115cf3c8f75b1afbe3274f02c1529e1ce3a81
48
+ end
31
49
  end
32
50
 
33
51
  def write_config(path, data)
34
52
  FileUtils.mkdir_p(File.dirname(path))
35
- File.open(path, "w") {|f| f.write data }
53
+ Fluent::FileWrapper.open(path, "w") {|f| f.write data }
36
54
  end
37
55
 
38
56
 
39
57
  def test_system_config
40
- opts = Fluent::Supervisor.default_options
41
- sv = Fluent::Supervisor.new(opts)
58
+ sv = Fluent::Supervisor.new({})
42
59
  conf_data = <<-EOC
43
60
  <system>
44
61
  rpc_endpoint 127.0.0.1:24445
45
- suppress_repeated_stacktrace true
62
+ suppress_repeated_stacktrace false
46
63
  suppress_config_dump true
47
64
  without_source true
48
65
  enable_get_dump true
49
66
  process_name "process_name"
50
67
  log_level info
51
- root_dir #{TMP_ROOT_DIR}
68
+ root_dir #{@tmp_root_dir}
52
69
  <log>
53
70
  format json
54
71
  time_format %Y
@@ -70,13 +87,13 @@ class SupervisorTest < ::Test::Unit::TestCase
70
87
  sys_conf = sv.__send__(:build_system_config, conf)
71
88
 
72
89
  assert_equal '127.0.0.1:24445', sys_conf.rpc_endpoint
73
- assert_equal true, sys_conf.suppress_repeated_stacktrace
90
+ assert_equal false, sys_conf.suppress_repeated_stacktrace
74
91
  assert_equal true, sys_conf.suppress_config_dump
75
92
  assert_equal true, sys_conf.without_source
76
93
  assert_equal true, sys_conf.enable_get_dump
77
94
  assert_equal "process_name", sys_conf.process_name
78
95
  assert_equal 2, sys_conf.log_level
79
- assert_equal TMP_ROOT_DIR, sys_conf.root_dir
96
+ assert_equal @tmp_root_dir, sys_conf.root_dir
80
97
  assert_equal :json, sys_conf.log.format
81
98
  assert_equal '%Y', sys_conf.log.time_format
82
99
  counter_server = sys_conf.counter_server
@@ -90,26 +107,146 @@ class SupervisorTest < ::Test::Unit::TestCase
90
107
  assert_equal 2, counter_client.timeout
91
108
  end
92
109
 
93
- def test_main_process_signal_handlers
110
+ sub_test_case "yaml config" do
111
+ def parse_yaml(yaml)
112
+ context = Kernel.binding
113
+
114
+ config = nil
115
+ Tempfile.open do |file|
116
+ file.puts(yaml)
117
+ file.flush
118
+ s = Fluent::Config::YamlParser::Loader.new(context).load(Pathname.new(file))
119
+ config = Fluent::Config::YamlParser::Parser.new(s).build.to_element
120
+ end
121
+ config
122
+ end
123
+
124
+ def test_system_config
125
+ sv = Fluent::Supervisor.new({})
126
+ conf_data = <<-EOC
127
+ system:
128
+ rpc_endpoint: 127.0.0.1:24445
129
+ suppress_repeated_stacktrace: true
130
+ suppress_config_dump: true
131
+ without_source: true
132
+ enable_get_dump: true
133
+ process_name: "process_name"
134
+ log_level: info
135
+ root_dir: !fluent/s "#{@tmp_root_dir}"
136
+ log:
137
+ format: json
138
+ time_format: "%Y"
139
+ counter_server:
140
+ bind: 127.0.0.1
141
+ port: 24321
142
+ scope: server1
143
+ backup_path: /tmp/backup
144
+ counter_client:
145
+ host: 127.0.0.1
146
+ port: 24321
147
+ timeout: 2
148
+ EOC
149
+ conf = parse_yaml(conf_data)
150
+ sys_conf = sv.__send__(:build_system_config, conf)
151
+
152
+ counter_client = sys_conf.counter_client
153
+ counter_server = sys_conf.counter_server
154
+ assert_equal(
155
+ [
156
+ '127.0.0.1:24445',
157
+ true,
158
+ true,
159
+ true,
160
+ true,
161
+ "process_name",
162
+ 2,
163
+ @tmp_root_dir,
164
+ :json,
165
+ '%Y',
166
+ '127.0.0.1',
167
+ 24321,
168
+ 'server1',
169
+ '/tmp/backup',
170
+ '127.0.0.1',
171
+ 24321,
172
+ 2,
173
+ ],
174
+ [
175
+ sys_conf.rpc_endpoint,
176
+ sys_conf.suppress_repeated_stacktrace,
177
+ sys_conf.suppress_config_dump,
178
+ sys_conf.without_source,
179
+ sys_conf.enable_get_dump,
180
+ sys_conf.process_name,
181
+ sys_conf.log_level,
182
+ sys_conf.root_dir,
183
+ sys_conf.log.format,
184
+ sys_conf.log.time_format,
185
+ counter_server.bind,
186
+ counter_server.port,
187
+ counter_server.scope,
188
+ counter_server.backup_path,
189
+ counter_client.host,
190
+ counter_client.port,
191
+ counter_client.timeout,
192
+ ])
193
+ end
194
+ end
195
+
196
+ def test_usr1_in_main_process_signal_handlers
94
197
  omit "Windows cannot handle signals" if Fluent.windows?
95
198
 
96
199
  create_info_dummy_logger
97
200
 
98
- opts = Fluent::Supervisor.default_options
99
- sv = Fluent::Supervisor.new(opts)
201
+ sv = Fluent::Supervisor.new({})
100
202
  sv.send(:install_main_process_signal_handlers)
101
203
 
102
- begin
103
- Process.kill :USR1, $$
104
- rescue
105
- end
204
+ Process.kill :USR1, Process.pid
106
205
 
107
206
  sleep 1
108
207
 
109
- info_msg = '[info]: force flushing buffered events' + "\n"
208
+ info_msg = "[info]: force flushing buffered events\n"
110
209
  assert{ $log.out.logs.first.end_with?(info_msg) }
111
210
  ensure
112
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
211
+ $log.out.reset if $log&.out&.respond_to?(:reset)
212
+ end
213
+
214
+ def test_cont_in_main_process_signal_handlers
215
+ omit "Windows cannot handle signals" if Fluent.windows?
216
+
217
+ sv = Fluent::Supervisor.new({})
218
+ sv.send(:install_main_process_signal_handlers)
219
+
220
+ Process.kill :CONT, Process.pid
221
+
222
+ sleep 1
223
+
224
+ assert{ File.exist?(@sigdump_path) }
225
+ ensure
226
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
227
+ end
228
+
229
+ def test_term_cont_in_main_process_signal_handlers
230
+ omit "Windows cannot handle signals" if Fluent.windows?
231
+
232
+ create_debug_dummy_logger
233
+
234
+ sv = Fluent::Supervisor.new({})
235
+ sv.send(:install_main_process_signal_handlers)
236
+
237
+ Process.kill :TERM, Process.pid
238
+ Process.kill :CONT, Process.pid
239
+
240
+ sleep 1
241
+
242
+ debug_msg = "[debug]: fluentd main process get SIGTERM\n"
243
+ logs = $log.out.logs
244
+ assert{ logs.any?{|log| log.include?(debug_msg) } }
245
+
246
+ assert{ not File.exist?(@sigdump_path) }
247
+ ensure
248
+ $log.out.reset if $log&.out&.respond_to?(:reset)
249
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
113
250
  end
114
251
 
115
252
  def test_main_process_command_handlers
@@ -117,8 +254,7 @@ class SupervisorTest < ::Test::Unit::TestCase
117
254
 
118
255
  create_info_dummy_logger
119
256
 
120
- opts = Fluent::Supervisor.default_options
121
- sv = Fluent::Supervisor.new(opts)
257
+ sv = Fluent::Supervisor.new({})
122
258
  r, w = IO.pipe
123
259
  $stdin = r
124
260
  sv.send(:install_main_process_signal_handlers)
@@ -132,23 +268,21 @@ class SupervisorTest < ::Test::Unit::TestCase
132
268
 
133
269
  sleep 1
134
270
 
135
- info_msg = '[info]: force flushing buffered events' + "\n"
271
+ info_msg = "[info]: force flushing buffered events\n"
136
272
  assert{ $log.out.logs.first.end_with?(info_msg) }
137
273
  ensure
138
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
274
+ $log.out.reset if $log&.out&.respond_to?(:reset)
139
275
  end
140
276
 
141
- def test_supervisor_signal_handler
277
+ def test_usr1_in_supervisor_signal_handler
142
278
  omit "Windows cannot handle signals" if Fluent.windows?
143
279
 
144
280
  create_debug_dummy_logger
145
281
 
146
282
  server = DummyServer.new
147
283
  server.install_supervisor_signal_handlers
148
- begin
149
- Process.kill :USR1, $$
150
- rescue
151
- end
284
+
285
+ Process.kill :USR1, Process.pid
152
286
 
153
287
  sleep 1
154
288
 
@@ -156,12 +290,43 @@ class SupervisorTest < ::Test::Unit::TestCase
156
290
  logs = $log.out.logs
157
291
  assert{ logs.any?{|log| log.include?(debug_msg) } }
158
292
  ensure
159
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
293
+ $log.out.reset if $log&.out&.respond_to?(:reset)
294
+ end
295
+
296
+ def test_cont_in_supervisor_signal_handler
297
+ omit "Windows cannot handle signals" if Fluent.windows?
298
+
299
+ server = DummyServer.new
300
+ server.install_supervisor_signal_handlers
301
+
302
+ Process.kill :CONT, Process.pid
303
+
304
+ sleep 1
305
+
306
+ assert{ File.exist?(@sigdump_path) }
307
+ ensure
308
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
309
+ end
310
+
311
+ def test_term_cont_in_supervisor_signal_handler
312
+ omit "Windows cannot handle signals" if Fluent.windows?
313
+
314
+ server = DummyServer.new
315
+ server.install_supervisor_signal_handlers
316
+
317
+ Process.kill :TERM, Process.pid
318
+ Process.kill :CONT, Process.pid
319
+
320
+ assert{ not File.exist?(@sigdump_path) }
321
+ ensure
322
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
160
323
  end
161
324
 
162
325
  def test_windows_shutdown_event
163
326
  omit "Only for Windows platform" unless Fluent.windows?
164
327
 
328
+ create_debug_dummy_logger
329
+
165
330
  server = DummyServer.new
166
331
  def server.config
167
332
  {:signame => "TestFluentdEvent"}
@@ -184,7 +349,7 @@ class SupervisorTest < ::Test::Unit::TestCase
184
349
  logs = $log.out.logs
185
350
  assert{ logs.any?{|log| log.include?(debug_msg) } }
186
351
  ensure
187
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
352
+ $log.out.reset if $log&.out&.respond_to?(:reset)
188
353
  end
189
354
 
190
355
  def test_supervisor_event_handler
@@ -210,19 +375,66 @@ class SupervisorTest < ::Test::Unit::TestCase
210
375
  logs = $log.out.logs
211
376
  assert{ logs.any?{|log| log.include?(debug_msg) } }
212
377
  ensure
213
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
378
+ $log.out.reset if $log&.out&.respond_to?(:reset)
214
379
  end
215
380
 
216
- def test_rpc_server
381
+ data("Normal", {raw_path: "C:\\Windows\\Temp\\sigdump.log", expected: "C:\\Windows\\Temp\\sigdump-#{Process.pid}.log"})
382
+ data("UNIX style", {raw_path: "/Windows/Temp/sigdump.log", expected: "/Windows/Temp/sigdump-#{Process.pid}.log"})
383
+ data("No extension", {raw_path: "C:\\Windows\\Temp\\sigdump", expected: "C:\\Windows\\Temp\\sigdump-#{Process.pid}"})
384
+ data("Multi-extension", {raw_path: "C:\\Windows\\Temp\\sig.dump.bk", expected: "C:\\Windows\\Temp\\sig.dump-#{Process.pid}.bk"})
385
+ def test_fluentsigdump_get_path_with_pid(data)
386
+ path = Fluent::FluentSigdump.get_path_with_pid(data[:raw_path])
387
+ assert_equal(data[:expected], path)
388
+ end
389
+
390
+ def test_supervisor_event_dump_windows
391
+ omit "Only for Windows, alternative to UNIX signals" unless Fluent.windows?
392
+
393
+ server = DummyServer.new
394
+ def server.config
395
+ {:signame => "TestFluentdEvent"}
396
+ end
397
+ server.install_windows_event_handler
398
+
399
+ assert_rr do
400
+ # Have to use mock because `Sigdump.dump` seems to be somehow incompatible with RR.
401
+ # The `mock(server).restart(true) { nil }` line in `test_rpc_server_windows` cause the next error.
402
+ # Failure: test_supervisor_event_dump_windows(SupervisorTest):
403
+ # class()
404
+ # Called 0 times.
405
+ # Expected 1 times.
406
+ # .../Ruby26-x64/lib/ruby/gems/2.6.0/gems/sigdump-0.2.4/lib/sigdump.rb:74:in `block in dump_object_count'
407
+ # 73: ObjectSpace.each_object {|o|
408
+ # 74: c = o.class <-- HERE!
409
+ mock(Sigdump).dump(anything)
410
+
411
+ begin
412
+ sleep 0.1 # Wait for starting windows event thread
413
+ event = Win32::Event.open("TestFluentdEvent_CONT")
414
+ event.set
415
+ event.close
416
+ sleep 1.0 # Wait for dumping
417
+ ensure
418
+ server.stop_windows_event_thread
419
+ end
420
+ end
421
+ end
422
+
423
+ data(:ipv4 => ["0.0.0.0", "127.0.0.1", false],
424
+ :ipv6 => ["[::]", "[::1]", true],
425
+ :localhost_ipv4 => ["localhost", "127.0.0.1", false])
426
+ def test_rpc_server(data)
217
427
  omit "Windows cannot handle signals" if Fluent.windows?
218
428
 
429
+ bindaddr, localhost, ipv6 = data
430
+ omit "IPv6 is not supported on this environment" if ipv6 && !ipv6_enabled?
431
+
219
432
  create_info_dummy_logger
220
433
 
221
- opts = Fluent::Supervisor.default_options
222
- sv = Fluent::Supervisor.new(opts)
434
+ sv = Fluent::Supervisor.new({})
223
435
  conf_data = <<-EOC
224
436
  <system>
225
- rpc_endpoint 0.0.0.0:24447
437
+ rpc_endpoint "#{bindaddr}:24447"
226
438
  </system>
227
439
  EOC
228
440
  conf = Fluent::Config.parse(conf_data, "(test)", "(test_dir)", true)
@@ -235,8 +447,8 @@ class SupervisorTest < ::Test::Unit::TestCase
235
447
  server.run_rpc_server
236
448
 
237
449
  sv.send(:install_main_process_signal_handlers)
238
- response = Net::HTTP.get(URI.parse('http://127.0.0.1:24447/api/plugins.flushBuffers'))
239
- info_msg = '[info]: force flushing buffered events' + "\n"
450
+ response = Net::HTTP.get(URI.parse("http://#{localhost}:24447/api/plugins.flushBuffers"))
451
+ info_msg = "[info]: force flushing buffered events\n"
240
452
 
241
453
  server.stop_rpc_server
242
454
 
@@ -250,16 +462,43 @@ class SupervisorTest < ::Test::Unit::TestCase
250
462
  $log.out.reset if $log.out.is_a?(Fluent::Test::DummyLogDevice)
251
463
  end
252
464
 
253
- def test_rpc_server_windows
465
+ data(:no_port => ["127.0.0.1"],
466
+ :invalid_addr => ["*:24447"])
467
+ def test_invalid_rpc_endpoint(data)
468
+ endpoint = data[0]
469
+
470
+ sv = Fluent::Supervisor.new({})
471
+ conf_data = <<-EOC
472
+ <system>
473
+ rpc_endpoint "#{endpoint}"
474
+ </system>
475
+ EOC
476
+ conf = Fluent::Config.parse(conf_data, "(test)", "(test_dir)", true)
477
+ sys_conf = sv.__send__(:build_system_config, conf)
478
+
479
+ server = DummyServer.new
480
+ server.rpc_endpoint = sys_conf.rpc_endpoint
481
+
482
+ assert_raise(Fluent::ConfigError.new("Invalid rpc_endpoint: #{endpoint}")) do
483
+ server.run_rpc_server
484
+ end
485
+ end
486
+
487
+ data(:ipv4 => ["0.0.0.0", "127.0.0.1", false],
488
+ :ipv6 => ["[::]", "[::1]", true],
489
+ :localhost_ipv4 => ["localhost", "127.0.0.1", true])
490
+ def test_rpc_server_windows(data)
254
491
  omit "Only for windows platform" unless Fluent.windows?
255
492
 
493
+ bindaddr, localhost, ipv6 = data
494
+ omit "IPv6 is not supported on this environment" if ipv6 && !ipv6_enabled?
495
+
256
496
  create_info_dummy_logger
257
497
 
258
- opts = Fluent::Supervisor.default_options
259
- sv = Fluent::Supervisor.new(opts)
498
+ sv = Fluent::Supervisor.new({})
260
499
  conf_data = <<-EOC
261
500
  <system>
262
- rpc_endpoint 0.0.0.0:24447
501
+ rpc_endpoint "#{bindaddr}:24447"
263
502
  </system>
264
503
  EOC
265
504
  conf = Fluent::Config.parse(conf_data, "(test)", "(test_dir)", true)
@@ -277,42 +516,23 @@ class SupervisorTest < ::Test::Unit::TestCase
277
516
  server.run_rpc_server
278
517
 
279
518
  mock(server).restart(true) { nil }
280
- response = Net::HTTP.get(URI.parse('http://127.0.0.1:24447/api/plugins.flushBuffers'))
519
+ response = Net::HTTP.get(URI.parse("http://#{localhost}:24447/api/plugins.flushBuffers"))
281
520
 
282
521
  server.stop_rpc_server
283
522
  assert_equal('{"ok":true}', response)
284
523
  end
285
524
 
286
- def test_load_config
287
- tmp_dir = "#{TMP_DIR}/dir/test_load_config.conf"
288
- conf_info_str = %[
289
- <system>
290
- log_level info
291
- </system>
292
- ]
293
- conf_debug_str = %[
294
- <system>
295
- log_level debug
296
- </system>
297
- ]
298
- now = Time.now
299
- Timecop.freeze(now)
300
-
301
- write_config tmp_dir, conf_info_str
302
-
525
+ def test_serverengine_config
303
526
  params = {}
304
527
  params['workers'] = 1
528
+ params['fluentd_conf_path'] = "fluentd.conf"
305
529
  params['use_v1_config'] = true
306
- params['log_path'] = 'test/tmp/supervisor/log'
307
- params['suppress_repeated_stacktrace'] = true
308
- params['log_level'] = Fluent::Log::LEVEL_INFO
309
530
  params['conf_encoding'] = 'utf-8'
310
- load_config_proc = Proc.new { Fluent::Supervisor.load_config(tmp_dir, params) }
531
+ params['log_level'] = Fluent::Log::LEVEL_INFO
532
+ load_config_proc = Proc.new { Fluent::Supervisor.serverengine_config(params) }
311
533
 
312
- # first call
313
534
  se_config = load_config_proc.call
314
535
  assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
315
- assert_equal true, se_config[:suppress_repeated_stacktrace]
316
536
  assert_equal 'spawn', se_config[:worker_type]
317
537
  assert_equal 1, se_config[:workers]
318
538
  assert_equal false, se_config[:log_stdin]
@@ -320,99 +540,23 @@ class SupervisorTest < ::Test::Unit::TestCase
320
540
  assert_equal false, se_config[:log_stderr]
321
541
  assert_equal true, se_config[:enable_heartbeat]
322
542
  assert_equal false, se_config[:auto_heartbeat]
543
+ assert_equal "fluentd.conf", se_config[:config_path]
323
544
  assert_equal false, se_config[:daemonize]
324
545
  assert_nil se_config[:pid_path]
325
-
326
- # second call immediately(reuse config)
327
- se_config = load_config_proc.call
328
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
329
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
330
- assert_nil pre_config_mtime
331
- assert_nil pre_loadtime
332
-
333
- Timecop.freeze(now + 5)
334
-
335
- # third call after 5 seconds(don't reuse config)
336
- se_config = load_config_proc.call
337
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
338
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
339
- assert_not_nil pre_config_mtime
340
- assert_not_nil pre_loadtime
341
-
342
- # forth call immediately(reuse config)
343
- se_config = load_config_proc.call
344
- # test that pre_config_mtime and pre_loadtime are not changed from previous one because reused pre_config
345
- assert_equal pre_config_mtime, se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
346
- assert_equal pre_loadtime, se_config[:windows_daemon_cmdline][5]['pre_loadtime']
347
-
348
- write_config tmp_dir, conf_debug_str
349
-
350
- # fifth call after changed conf file(don't reuse config)
351
- se_config = load_config_proc.call
352
- assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
353
- ensure
354
- Timecop.return
355
546
  end
356
547
 
357
- def test_load_config_for_logger
358
- tmp_dir = "#{TMP_DIR}/dir/test_load_config_log.conf"
359
- conf_info_str = %[
360
- <system>
361
- <log>
362
- format json
363
- time_format %FT%T.%L%z
364
- </log>
365
- </system>
366
- ]
367
- write_config tmp_dir, conf_info_str
368
- params = {
369
- 'use_v1_config' => true,
370
- 'conf_encoding' => 'utf8',
371
- 'log_level' => Fluent::Log::LEVEL_INFO,
372
- 'log_path' => 'test/tmp/supervisor/log',
373
-
374
- 'workers' => 1,
375
- 'log_format' => :json,
376
- 'log_time_format' => '%FT%T.%L%z',
377
- }
378
-
379
- r = Fluent::Supervisor.load_config(tmp_dir, params)
380
- assert_equal :json, r[:logger].format
381
- assert_equal '%FT%T.%L%z', r[:logger].time_format
382
- end
383
-
384
- def test_load_config_for_daemonize
385
- tmp_dir = "#{TMP_DIR}/dir/test_load_config.conf"
386
- conf_info_str = %[
387
- <system>
388
- log_level info
389
- </system>
390
- ]
391
- conf_debug_str = %[
392
- <system>
393
- log_level debug
394
- </system>
395
- ]
396
-
397
- now = Time.now
398
- Timecop.freeze(now)
399
-
400
- write_config tmp_dir, conf_info_str
401
-
548
+ def test_serverengine_config_for_daemonize
402
549
  params = {}
403
550
  params['workers'] = 1
551
+ params['fluentd_conf_path'] = "fluentd.conf"
404
552
  params['use_v1_config'] = true
405
- params['log_path'] = 'test/tmp/supervisor/log'
406
- params['suppress_repeated_stacktrace'] = true
553
+ params['conf_encoding'] = 'utf-8'
407
554
  params['log_level'] = Fluent::Log::LEVEL_INFO
408
555
  params['daemonize'] = './fluentd.pid'
409
- params['conf_encoding'] = 'utf-8'
410
- load_config_proc = Proc.new { Fluent::Supervisor.load_config(tmp_dir, params) }
556
+ load_config_proc = Proc.new { Fluent::Supervisor.serverengine_config(params) }
411
557
 
412
- # first call
413
558
  se_config = load_config_proc.call
414
559
  assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
415
- assert_equal true, se_config[:suppress_repeated_stacktrace]
416
560
  assert_equal 'spawn', se_config[:worker_type]
417
561
  assert_equal 1, se_config[:workers]
418
562
  assert_equal false, se_config[:log_stdin]
@@ -420,136 +564,212 @@ class SupervisorTest < ::Test::Unit::TestCase
420
564
  assert_equal false, se_config[:log_stderr]
421
565
  assert_equal true, se_config[:enable_heartbeat]
422
566
  assert_equal false, se_config[:auto_heartbeat]
567
+ assert_equal "fluentd.conf", se_config[:config_path]
423
568
  assert_equal true, se_config[:daemonize]
424
569
  assert_equal './fluentd.pid', se_config[:pid_path]
425
-
426
- # second call immediately(reuse config)
427
- se_config = load_config_proc.call
428
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
429
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
430
- assert_nil pre_config_mtime
431
- assert_nil pre_loadtime
432
-
433
- Timecop.freeze(now + 5)
434
-
435
- # third call after 6 seconds(don't reuse config)
436
- se_config = load_config_proc.call
437
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
438
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
439
- assert_not_nil pre_config_mtime
440
- assert_not_nil pre_loadtime
441
-
442
- # forth call immediately(reuse config)
443
- se_config = load_config_proc.call
444
- # test that pre_config_mtime and pre_loadtime are not changed from previous one because reused pre_config
445
- assert_equal pre_config_mtime, se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
446
- assert_equal pre_loadtime, se_config[:windows_daemon_cmdline][5]['pre_loadtime']
447
-
448
- write_config tmp_dir, conf_debug_str
449
-
450
- # fifth call after changed conf file(don't reuse config)
451
- se_config = load_config_proc.call
452
- assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
453
- ensure
454
- Timecop.return
455
570
  end
456
571
 
457
- def test_logger
458
- opts = Fluent::Supervisor.default_options
459
- sv = Fluent::Supervisor.new(opts)
460
- log = sv.instance_variable_get(:@log)
461
- log.init(:standalone, 0)
462
- logger = $log.instance_variable_get(:@logger)
572
+ sub_test_case "init logger" do
573
+ data(supervisor: true)
574
+ data(worker: false)
575
+ def test_init_for_logger(supervisor)
576
+ tmp_conf_path = "#{@tmp_dir}/dir/test_init_for_logger.conf"
577
+ conf_info_str = <<~EOC
578
+ <system>
579
+ log_level warn # To suppress logs
580
+ suppress_repeated_stacktrace false
581
+ ignore_repeated_log_interval 10s
582
+ ignore_same_log_interval 20s
583
+ <log>
584
+ format json
585
+ time_format %FT%T.%L%z
586
+ </log>
587
+ </system>
588
+ EOC
589
+ write_config tmp_conf_path, conf_info_str
590
+
591
+ s = Fluent::Supervisor.new({config_path: tmp_conf_path})
592
+ s.configure(supervisor: supervisor)
593
+
594
+ assert_equal :json, $log.format
595
+ assert_equal '%FT%T.%L%z', $log.time_format
596
+ assert_equal false, $log.suppress_repeated_stacktrace
597
+ assert_equal 10, $log.ignore_repeated_log_interval
598
+ assert_equal 20, $log.ignore_same_log_interval
599
+ end
463
600
 
464
- assert_equal Fluent::Log::LEVEL_INFO, $log.level
601
+ data(
602
+ daily_age: 'daily',
603
+ weekly_age: 'weekly',
604
+ monthly_age: 'monthly',
605
+ integer_age: 2,
606
+ )
607
+ def test_logger_with_rotate_age_and_rotate_size(rotate_age)
608
+ config_path = "#{@tmp_dir}/empty.conf"
609
+ write_config config_path, ""
610
+
611
+ sv = Fluent::Supervisor.new(
612
+ config_path: config_path,
613
+ log_path: "#{@tmp_dir}/test",
614
+ log_rotate_age: rotate_age,
615
+ log_rotate_size: 10,
616
+ )
617
+ sv.__send__(:setup_global_logger)
618
+
619
+ assert_equal Fluent::LogDeviceIO, $log.out.class
620
+ assert_equal rotate_age, $log.out.instance_variable_get(:@shift_age)
621
+ assert_equal 10, $log.out.instance_variable_get(:@shift_size)
622
+ end
465
623
 
466
- # test that DamonLogger#level= overwrites Fluent.log#level
467
- logger.level = 'debug'
468
- assert_equal Fluent::Log::LEVEL_DEBUG, $log.level
624
+ def test_can_start_with_rotate_but_no_log_path
625
+ config_path = "#{@tmp_dir}/empty.conf"
626
+ write_config config_path, ""
469
627
 
470
- assert_equal 5, logger.instance_variable_get(:@rotate_age)
471
- assert_equal 1048576, logger.instance_variable_get(:@rotate_size)
472
- end
628
+ sv = Fluent::Supervisor.new(
629
+ config_path: config_path,
630
+ log_rotate_age: 5,
631
+ )
632
+ sv.__send__(:setup_global_logger)
473
633
 
474
- data(
475
- daily_age: 'daily',
476
- weekly_age: 'weekly',
477
- monthly_age: 'monthly',
478
- integer_age: 2,
479
- )
480
- def test_logger_with_rotate_age_and_rotate_size(rotate_age)
481
- opts = Fluent::Supervisor.default_options.merge(
482
- log_path: "#{TMP_DIR}/test", log_rotate_age: rotate_age, log_rotate_size: 10
483
- )
484
- sv = Fluent::Supervisor.new(opts)
485
- log = sv.instance_variable_get(:@log)
486
- log.init(:standalone, 0)
634
+ assert_true $log.stdout?
635
+ end
487
636
 
488
- assert_equal Fluent::LogDeviceIO, $log.out.class
489
- assert_equal rotate_age, $log.out.instance_variable_get(:@shift_age)
490
- assert_equal 10, $log.out.instance_variable_get(:@shift_size)
491
- end
637
+ sub_test_case "system log rotation" do
638
+ def parse_text(text)
639
+ basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
640
+ Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
641
+ end
492
642
 
493
- sub_test_case "system log rotation" do
494
- def parse_text(text)
495
- basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
496
- Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
497
- end
643
+ def test_override_default_log_rotate
644
+ Tempfile.open do |file|
645
+ config = parse_text(<<-EOS)
646
+ <system>
647
+ <log>
648
+ rotate_age 3
649
+ rotate_size 300
650
+ </log>
651
+ </system>
652
+ EOS
653
+ file.puts(config)
654
+ file.flush
655
+ sv = Fluent::Supervisor.new({log_path: "#{@tmp_dir}/test.log", config_path: file.path})
656
+
657
+ sv.__send__(:setup_global_logger)
658
+ logger = $log.instance_variable_get(:@logger)
659
+
660
+ assert_equal Fluent::LogDeviceIO, $log.out.class
661
+ assert_equal 3, $log.out.instance_variable_get(:@shift_age)
662
+ assert_equal 300, $log.out.instance_variable_get(:@shift_size)
663
+ end
664
+ end
498
665
 
499
- def test_override_default_log_rotate
500
- Tempfile.open do |file|
501
- config = parse_text(<<-EOS)
502
- <system>
503
- <log>
504
- rotate_age 3
505
- rotate_size 300
506
- </log>
507
- </system>
508
- EOS
509
- file.puts(config)
510
- file.flush
511
- opts = Fluent::Supervisor.default_options.merge(
512
- log_path: "#{TMP_DIR}/test.log", config_path: file.path
513
- )
514
- sv = Fluent::Supervisor.new(opts)
515
-
516
- log = sv.instance_variable_get(:@log)
517
- log.init(:standalone, 0)
518
- logger = $log.instance_variable_get(:@logger)
519
-
520
- assert_equal([3, 300],
521
- [logger.instance_variable_get(:@rotate_age),
522
- logger.instance_variable_get(:@rotate_size)])
666
+ def test_override_default_log_rotate_with_yaml_config
667
+ Tempfile.open do |file|
668
+ config = <<-EOS
669
+ system:
670
+ log:
671
+ rotate_age: 3
672
+ rotate_size: 300
673
+ EOS
674
+ file.puts(config)
675
+ file.flush
676
+ sv = Fluent::Supervisor.new({log_path: "#{@tmp_dir}/test.log", config_path: file.path, config_file_type: :yaml})
677
+
678
+ sv.__send__(:setup_global_logger)
679
+ logger = $log.instance_variable_get(:@logger)
680
+
681
+ assert_equal Fluent::LogDeviceIO, $log.out.class
682
+ assert_equal 3, $log.out.instance_variable_get(:@shift_age)
683
+ assert_equal 300, $log.out.instance_variable_get(:@shift_size)
684
+ end
523
685
  end
524
686
  end
525
- end
526
687
 
527
- def test_inline_config
528
- omit 'this feature is deprecated. see https://github.com/fluent/fluentd/issues/2711'
688
+ def test_log_level_affects
689
+ sv = Fluent::Supervisor.new({})
529
690
 
530
- opts = Fluent::Supervisor.default_options
531
- opts[:inline_config] = '-'
532
- sv = Fluent::Supervisor.new(opts)
533
- assert_equal '-', sv.instance_variable_get(:@inline_config)
691
+ c = Fluent::Config::Element.new('system', '', { 'log_level' => 'error' }, [])
692
+ stub(Fluent::Config).build { config_element('ROOT', '', {}, [c]) }
534
693
 
535
- inline_config = '<match *>\n@type stdout\n</match>'
536
- stub(STDIN).read { inline_config }
537
- stub(Fluent::Config).build # to skip
538
- stub(sv).build_system_config { Fluent::SystemConfig.new } # to skip
694
+ sv.configure
695
+ assert_equal Fluent::Log::LEVEL_ERROR, $log.level
696
+ end
539
697
 
540
- sv.configure
541
- assert_equal inline_config, sv.instance_variable_get(:@inline_config)
542
- end
698
+ data(supervisor: true)
699
+ data(worker: false)
700
+ def test_log_path(supervisor)
701
+ log_path = Pathname(@tmp_dir) + "fluentd.log"
702
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
703
+ write_config config_path.to_s, ""
704
+
705
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
706
+ assert_rr do
707
+ mock.proxy(File).chmod(0o777, log_path.parent.to_s).never
708
+ s.__send__(:setup_global_logger, supervisor: supervisor)
709
+ end
710
+
711
+ assert { log_path.parent.exist? }
712
+ ensure
713
+ $log.out.close
714
+ end
543
715
 
544
- def test_log_level_affects
545
- opts = Fluent::Supervisor.default_options
546
- sv = Fluent::Supervisor.new(opts)
716
+ data(supervisor: true)
717
+ data(worker: false)
718
+ def test_dir_permission(supervisor)
719
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
720
+
721
+ log_path = Pathname(@tmp_dir) + "fluentd.log"
722
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
723
+ conf = <<~EOC
724
+ <system>
725
+ dir_permission 0o777
726
+ </system>
727
+ EOC
728
+ write_config config_path.to_s, conf
729
+
730
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
731
+ assert_rr do
732
+ mock.proxy(File).chmod(0o777, log_path.parent.to_s).once
733
+ s.__send__(:setup_global_logger, supervisor: supervisor)
734
+ end
547
735
 
548
- c = Fluent::Config::Element.new('system', '', { 'log_level' => 'error' }, [])
549
- stub(Fluent::Config).build { config_element('ROOT', '', {}, [c]) }
736
+ assert { log_path.parent.exist? }
737
+ assert { (File.stat(log_path.parent).mode & 0xFFF) == 0o777 }
738
+ ensure
739
+ $log.out.close
740
+ end
550
741
 
551
- sv.configure
552
- assert_equal Fluent::Log::LEVEL_ERROR, $log.level
742
+ def test_files_for_each_process_with_rotate_on_windows
743
+ omit "Only for Windows." unless Fluent.windows?
744
+
745
+ log_path = Pathname(@tmp_dir) + "log" + "fluentd.log"
746
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
747
+ conf = <<~EOC
748
+ <system>
749
+ <log>
750
+ rotate_age 5
751
+ </log>
752
+ </system>
753
+ EOC
754
+ write_config config_path.to_s, conf
755
+
756
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
757
+ s.__send__(:setup_global_logger, supervisor: true)
758
+ $log.out.close
759
+
760
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
761
+ s.__send__(:setup_global_logger, supervisor: false)
762
+ $log.out.close
763
+
764
+ ENV["SERVERENGINE_WORKER_ID"] = "1"
765
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
766
+ s.__send__(:setup_global_logger, supervisor: false)
767
+ $log.out.close
768
+
769
+ assert { log_path.parent.entries.size == 5 } # [".", "..", "logfile.log", ...]
770
+ ensure
771
+ ENV.delete("SERVERENGINE_WORKER_ID")
772
+ end
553
773
  end
554
774
 
555
775
  def test_enable_shared_socket