Skip to content

Commit

Permalink
test in_tail: use safer method to cleanup
Browse files Browse the repository at this point in the history
This PR aims to fix in_tail test cases on Windows.

On Windows, when the file or directory is removed and created
frequently, there is a case that creating file or directory will fail.
This situation is caused by pending file or directory deletion which
is mentioned on win32 API document.

ref. https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#files

As a workaround, execute rename and remove method.

Signed-off-by: Kentaro Hayashi <[email protected]>
  • Loading branch information
kenhys committed Mar 8, 2021
1 parent 4cd2be4 commit aca881f
Showing 1 changed file with 37 additions and 10 deletions.
47 changes: 37 additions & 10 deletions test/plugin/test_in_tail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
require 'net/http'
require 'flexmock/test_unit'
require 'timecop'
require 'tmpdir'
require 'securerandom'

class TailInputTest < Test::Unit::TestCase
include FlexMock::TestCase
Expand All @@ -22,28 +24,53 @@ def teardown
end

def cleanup_directory(path)
unless Dir.exist?(path)
FileUtils.mkdir_p(path)
return
end

# On Windows, when the file or directory is removed and created
# frequently, there is a case that creating file or directory will
# fail. This situation is caused by pending file or directory
# deletion which is mentioned on win32 API document [1]
# As a workaround, execute rename and remove method.
#
# [1] https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#files
#
dir = File.join(Dir.tmpdir, SecureRandom.hex(10))
begin
FileUtils.rm_f(path, secure: true)
files = Dir.glob("*", base: path)
if files.empty?
FileUtils.mv(path, dir)
else
files.each do |name|
FileUtils.rm_f(File.join(path, name), secure: true)
end
# TODO: path should be renamed to dir here, but it raise access denied exception
end
# ensure files are closed for Windows, on which deleted files
# are still visible from filesystem
GC.start(full_mark: true, immediate_mark: true, immediate_sweep: true)
FileUtils.remove_entry_secure(dir, true)
rescue ArgumentError
FileUtils.rm_f(path) # For Ruby 2.6 or before.
end
if File.exist?(path)
FileUtils.remove_entry_secure(path, true)
FileUtils.rm_rf(dir) # For Ruby 2.6 or before.
end
FileUtils.mkdir_p(path)
end

def cleanup_file(path)
file = File.join(Dir.tmpdir, SecureRandom.hex(10))
begin
FileUtils.rm_f(path, secure: true)
FileUtils.mv(path, file)
FileUtils.rm_rf(file, secure: true)
rescue ArgumentError
FileUtils.rm_f(path) # For Ruby 2.6 or before.
FileUtils.rm_rf(file) # For Ruby 2.6 or before.
end
if File.exist?(path)
if File.exist?(file)
# ensure files are closed for Windows, on which deleted files
# are still visible from filesystem
GC.start(full_mark: true, immediate_mark: true, immediate_sweep: true)
FileUtils.remove_entry_secure(path, true)
FileUtils.remove_entry_secure(file, true)
end
end

Expand Down Expand Up @@ -1645,7 +1672,7 @@ def test_should_close_watcher_after_rotate_wait
f.puts "test1"
f.puts "test2"
}
target_info = create_target_info("#{TMP_DIR}/tail.txt")
target_info = Fluent::Plugin::TailInput::TargetInfo.new(path, File.stat(path).ino)
mock.proxy(Fluent::Plugin::TailInput::TailWatcher).new(target_info, anything, anything, true, true, anything, nil, anything).once
d.run(shutdown: false)
assert d.instance.instance_variable_get(:@tails)[target_info]
Expand Down

0 comments on commit aca881f

Please sign in to comment.