require_relative '../helper'
require 'tmpdir'
require 'fluent/plugin/base'
module FluentPluginBaseTest
class DummyPlugin < Fluent::Plugin::Base
end
end
class BaseTest < Test::Unit::TestCase
setup do
@p = FluentPluginBaseTest::DummyPlugin.new
end
test 'has methods for phases of plugin life cycle, and methods to know "super"s were correctly called or not' do
assert !@p.configured?
@p.configure(config_element())
assert @p.configured?
assert !@p.started?
@p.start
assert @p.start
assert !@p.stopped?
@p.stop
assert @p.stopped?
assert !@p.before_shutdown?
@p.before_shutdown
assert @p.before_shutdown?
assert !@p.shutdown?
@p.shutdown
assert @p.shutdown?
assert !@p.after_shutdown?
@p.after_shutdown
assert @p.after_shutdown?
assert !@p.closed?
@p.close
assert @p.closed?
assert !@p.terminated?
@p.terminate
assert @p.terminated?
end
test 'can access system config' do
assert @p.system_config
@p.system_config_override({'process_name' => 'mytest'})
assert_equal 'mytest', @p.system_config.process_name
end
test 'does not have router in default' do
assert !@p.has_router?
end
sub_test_case '#fluentd_worker_id' do
test 'returns 0 in default' do
assert_equal 0, @p.fluentd_worker_id
end
test 'returns the value specified via SERVERENGINE_WORKER_ID env variable' do
pre_value = ENV['SERVERENGINE_WORKER_ID']
begin
ENV['SERVERENGINE_WORKER_ID'] = 7.to_s
assert_equal 7, @p.fluentd_worker_id
ensure
ENV['SERVERENGINE_WORKER_ID'] = pre_value
end
end
end
test 'does not have root dir in default' do
assert_nil @p.plugin_root_dir
end
test 'is configurable by config_param and config_section' do
assert_nothing_raised do
class FluentPluginBaseTest::DummyPlugin2 < Fluent::Plugin::TestBase
config_param :myparam1, :string
config_section :mysection, multi: false do
config_param :myparam2, :integer
end
end
end
p2 = FluentPluginBaseTest::DummyPlugin2.new
assert_nothing_raised do
p2.configure(config_element('ROOT', '', {'myparam1' => 'myvalue1'}, [config_element('mysection', '', {'myparam2' => 99})]))
end
assert_equal 'myvalue1', p2.myparam1
assert_equal 99, p2.mysection.myparam2
end
test 'plugins are available with multi worker configuration in default' do
assert @p.multi_workers_ready?
end
test 'provides #string_safe_encoding to scrub invalid sequence string with info logging' do
logger = Fluent::Test::TestLogger.new
m = Module.new do
define_method(:log) do
logger
end
end
@p.extend m
assert_equal [], logger.logs
ret = @p.string_safe_encoding("abc\xff.\x01f"){|s| s.split(".") }
assert_equal ['abc?', "\u0001f"], ret
assert_equal 1, logger.logs.size
assert{ logger.logs.first.include?("invalid byte sequence is replaced in ") }
end
test 'generates worker lock path safely' do
Dir.mktmpdir("test-fluentd-lock-") do |lock_dir|
ENV['FLUENTD_LOCK_DIR'] = lock_dir
p = FluentPluginBaseTest::DummyPlugin.new
path = p.get_lock_path("Aa\\|=~/_123");
assert_equal lock_dir, File.dirname(path)
assert_equal "fluentd-Aa______123.lock", File.basename(path)
end
end
test 'can acquire inter-worker locking' do
Dir.mktmpdir("test-fluentd-lock-") do |lock_dir|
ENV['FLUENTD_LOCK_DIR'] = lock_dir
p = FluentPluginBaseTest::DummyPlugin.new
lock_path = p.get_lock_path("test_base")
p.acquire_worker_lock("test_base") do
# With LOCK_NB set, flock() returns `false` when the
# file is already locked.
File.open(lock_path, "w") do |f|
assert_equal false, f.flock(File::LOCK_EX|File::LOCK_NB)
end
end
# Lock should be release by now. In that case, flock
# must return 0.
File.open(lock_path, "w") do |f|
assert_equal 0, f.flock(File::LOCK_EX|File::LOCK_NB)
end
end
end
test '`ArgumentError` when `conf` is not `Fluent::Config::Element`' do
assert_raise ArgumentError.new('BUG: type of conf must be Fluent::Config::Element, but Hash is passed.') do
@p.configure({})
end
end
sub_test_case 'system_config.workers value after configure' do
def assert_system_config_workers_value(data)
conf = config_element()
conf.set_target_worker_ids(data[:target_worker_ids])
@p.configure(conf)
assert{ @p.system_config.workers == data[:expected] }
end
def stub_supervisor_mode
stub(Fluent::Engine).supervisor_mode { true }
stub(Fluent::Engine).worker_id { -1 }
end
sub_test_case 'with workers 3 ' do
setup do
system_config = Fluent::SystemConfig.new
system_config.workers = 3
stub(Fluent::Engine).system_config { system_config }
end
data(
'without directive',
{
target_worker_ids: [],
expected: 3
},
keep: true
)
data(
'with ',
{
target_worker_ids: [0],
expected: 1
},
keep: true
)
data(
'with ',
{
target_worker_ids: [0, 1],
expected: 2
},
keep: true
)
data(
'with ',
{
target_worker_ids: [0, 1, 2],
expected: 3
},
keep: true
)
test 'system_config.workers value after configure' do
assert_system_config_workers_value(data)
end
test 'system_config.workers value after configure with supervisor_mode' do
stub_supervisor_mode
assert_system_config_workers_value(data)
end
end
sub_test_case 'without directive' do
data(
'without directive',
{
target_worker_ids: [],
expected: 1
},
keep: true
)
data(
'with ',
{
target_worker_ids: [0],
expected: 1
},
keep: true
)
test 'system_config.workers value after configure' do
assert_system_config_workers_value(data)
end
test 'system_config.workers value after configure with supervisor_mode' do
stub_supervisor_mode
assert_system_config_workers_value(data)
end
end
end
end