Back to Repositories

Validating Plugin ID Management and Configuration in Fluentd

This test suite validates the plugin ID functionality in Fluentd, focusing on plugin identification, configuration, and root directory management. The tests ensure proper handling of plugin IDs and directory structures essential for Fluentd’s plugin system.

Test Coverage Overview

The test suite provides comprehensive coverage of Fluentd’s plugin ID system, including:
  • Plugin ID configuration validation
  • Default ID generation for unconfigured plugins
  • Root directory path management
  • Worker-specific directory handling
  • Directory permission settings
Key edge cases include testing with and without explicit IDs, worker ID environment variables, and different permission configurations.

Implementation Analysis

The testing approach utilizes Ruby’s Test::Unit framework with nested test cases for organized test grouping.
  • Uses sub_test_case blocks for logical test organization
  • Implements setup blocks for test initialization
  • Employs assertion methods for verification
  • Utilizes temporary directory management for filesystem tests

Technical Details

Testing infrastructure includes:
  • Test::Unit as the primary testing framework
  • FileUtils for directory manipulation
  • Environment variable management for worker ID testing
  • SystemConfig overwriting for configuration testing
  • Temporary directory structure for isolation

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Proper test isolation using temporary directories
  • Cleanup in setup/teardown blocks
  • Platform-specific test handling (Windows vs Unix)
  • Environment variable management with proper restoration
  • Systematic test organization using nested test cases

fluent/fluentd

test/test_plugin_id.rb

            
require_relative 'helper'
require 'fluent/plugin/base'
require 'fluent/system_config'
require 'fileutils'

class PluginIdTest < Test::Unit::TestCase
  TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/tmp/plugin_id/#{ENV['TEST_ENV_NUMBER']}")

  class MyPlugin < Fluent::Plugin::Base
    include Fluent::PluginId
  end

  setup do
    @p = MyPlugin.new
  end

  sub_test_case '#plugin_id_for_test?' do
    test 'returns true always in test files' do
      assert @p.plugin_id_for_test?
    end

    test 'returns false always out of test files' do
      # TODO: no good way to write this test....
    end
  end

  sub_test_case 'configured without @id' do
    setup do
      @p.configure(config_element())
    end

    test '#plugin_id_configured? returns false' do
      assert_false @p.plugin_id_configured?
    end

    test '#plugin_id returns object_id based string' do
      assert_kind_of String, @p.plugin_id
      assert @p.plugin_id =~ /^object:[0-9a-f]+/
    end

    test '#plugin_root_dir returns nil' do
      assert_nil @p.plugin_root_dir
    end
  end

  sub_test_case 'configured with @id' do
    setup do
      FileUtils.rm_rf(TMP_DIR)
      FileUtils.mkdir_p(TMP_DIR)
      @p.configure(config_element('ROOT', '', {'@id' => 'testing_plugin_id'}))
    end

    test '#plugin_id_configured? returns true' do
      assert @p.plugin_id_configured?
    end

    test '#plugin_id returns the configured value' do
      assert_equal 'testing_plugin_id', @p.plugin_id
    end

    test '#plugin_root_dir returns nil without system root directory configuration' do
      assert_nil @p.plugin_root_dir
    end

    test '#plugin_root_dir returns an existing directory path frozen String' do
      root_dir = Fluent::SystemConfig.overwrite_system_config('root_dir' => File.join(TMP_DIR, "myroot")) do
        @p.plugin_root_dir
      end
      assert_kind_of String, root_dir
      assert Dir.exist?(root_dir)
      assert root_dir =~ %r!/worker0/!
      assert root_dir.frozen?
    end

    test '#plugin_root_dir returns the same value for 2nd or more call' do
      root_dir = Fluent::SystemConfig.overwrite_system_config('root_dir' => File.join(TMP_DIR, "myroot")) do
        @p.plugin_root_dir
      end
      twice = Fluent::SystemConfig.overwrite_system_config('root_dir' => File.join(TMP_DIR, "myroot")) do
        @p.plugin_root_dir
      end
      assert_equal root_dir.object_id, twice.object_id
    end

    test '#plugin_root_dir referres SERVERENGINE_WORKER_ID environment path to create it' do
      prev_env_val = ENV['SERVERENGINE_WORKER_ID']
      begin
        ENV['SERVERENGINE_WORKER_ID'] = '7'
        root_dir = Fluent::SystemConfig.overwrite_system_config('root_dir' => File.join(TMP_DIR, "myroot")) do
          @p.plugin_root_dir
        end
        assert_kind_of String, root_dir
        assert Dir.exist?(root_dir)
        assert root_dir =~ %r!/worker7/!
        assert root_dir.frozen?
      ensure
        ENV['SERVERENGINE_WORKER_ID'] = prev_env_val
      end
    end

    test '#plugin_root_dir create dirctory with specify mode if not exists ' do
      omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?

      root_dir = Fluent::SystemConfig.overwrite_system_config({ 'root_dir' => File.join(TMP_DIR, "myroot"), 'dir_permission' => '0777' }) do
        @p.plugin_root_dir
      end

      assert_equal '777', File.stat(root_dir).mode.to_s(8)[-3, 3]
    end

    test '#plugin_root_dir create dirctory with default permission if not exists ' do
      root_dir = Fluent::SystemConfig.overwrite_system_config({ 'root_dir' => File.join(TMP_DIR, "myroot") }) do
        @p.plugin_root_dir
      end

      assert_equal '755', File.stat(root_dir).mode.to_s(8)[-3, 3]
    end
  end
end