Back to Repositories

Testing Apache Error Log Parser Implementation in Fluentd

This test suite validates the Apache Error Parser functionality in Fluentd, ensuring accurate parsing of Apache error log entries. The tests verify timestamp parsing, error levels, client information extraction, and message handling in various log formats.

Test Coverage Overview

The test suite provides comprehensive coverage of Apache error log parsing scenarios:

  • Standard error log parsing with client information
  • Error logs containing PID information
  • Notice-level logs without client details
  • Timestamp parsing and validation
  • Record field extraction and verification

Implementation Analysis

The testing approach uses Fluentd’s Parser Driver framework to validate the ApacheErrorParser plugin. Each test case follows a consistent pattern of creating a parser instance, feeding sample log entries, and asserting the parsed output structure.

The implementation leverages Ruby’s block-based testing style and Fluentd’s event_time helper for timestamp handling.

Technical Details

Testing tools and components include:

  • Fluent::Test::Driver::Parser for parser testing
  • Test::Unit framework for assertions
  • Fluent::Plugin::ApacheErrorParser as the target component
  • Custom setup method for test data initialization
  • Event time parsing utilities

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test cases with clear purpose
  • Consistent setup and teardown patterns
  • Comprehensive edge case coverage
  • Clear assertion messages
  • Efficient test data organization

fluent/fluentd

test/plugin/test_parser_apache_error.rb

            
require_relative '../helper'
require 'fluent/test/driver/parser'
require 'fluent/plugin/parser_apache_error'

class ApacheErrorParserTest < ::Test::Unit::TestCase
  def setup
    Fluent::Test.setup
    @expected = {
      'level' => 'error',
      'client' => '127.0.0.1',
      'message' => 'client denied by server configuration'
    }
  end

  def create_driver
    Fluent::Test::Driver::Parser.new(Fluent::Plugin::ApacheErrorParser.new).configure({})
  end

  def test_parse
    d = create_driver
    d.instance.parse('[Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] client denied by server configuration') { |time, record|
      assert_equal(event_time('Wed Oct 11 14:32:52 2000'), time)
      assert_equal(@expected, record)
    }
  end

  def test_parse_with_pid
    d = create_driver
    d.instance.parse('[Wed Oct 11 14:32:52 2000] [error] [pid 1000] [client 127.0.0.1] client denied by server configuration') { |time, record|
      assert_equal(event_time('Wed Oct 11 14:32:52 2000'), time)
      assert_equal(@expected.merge('pid' => '1000'), record)
    }
  end

  def test_parse_without_client
    d = create_driver
    d.instance.parse('[Wed Oct 11 14:32:52 2000] [notice] Apache/2.2.15 (Unix) DAV/2 configured -- resuming normal operations') { |time, record|
      assert_equal(event_time('Wed Oct 11 14:32:52 2000'), time)
      assert_equal({
                     'level' => 'notice',
                     'message' => 'Apache/2.2.15 (Unix) DAV/2 configured -- resuming normal operations'
                   }, record)
    }
  end
end