Add unit tests for parsers, analyzer, and CLI
Some checks failed
CI / test (3.10) (push) Has started running
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-02-02 08:08:21 +00:00
parent cdfef71866
commit a4c909cd9d

191
tests/unit/test_parsers.py Normal file
View File

@@ -0,0 +1,191 @@
"""Unit tests for log parsers."""
import pytest
from loglens.parsers.base import LogFormat, ParsedLogEntry
from loglens.parsers.json_parser import JSONParser
from loglens.parsers.syslog_parser import SyslogParser
from loglens.parsers.apache_parser import ApacheParser
from loglens.parsers.factory import ParserFactory
class TestJSONParser:
"""Tests for JSON parser."""
def test_parse_valid_json(self):
"""Test parsing valid JSON log entry."""
parser = JSONParser()
line = '{"timestamp": "2024-01-15T10:30:00Z", "level": "INFO", "message": "Test"}'
entry = parser.parse(line, 1)
assert entry is not None
assert entry.raw_line == line
assert entry.line_number == 1
assert entry.message == "Test"
assert entry.level == "INFO"
def test_can_parse_json(self):
"""Test can_parse detection for JSON."""
parser = JSONParser()
assert parser.can_parse('{"key": "value"}')
assert parser.can_parse('[1, 2, 3]')
assert not parser.can_parse("not json")
assert not parser.can_parse("")
def test_parse_invalid_json(self):
"""Test parsing invalid JSON returns error entry."""
parser = JSONParser()
line = '{"invalid": json}'
entry = parser.parse(line, 1)
assert entry is not None
assert entry.severity == "error"
assert "JSON parse error" in entry.message
def test_parse_batch(self):
"""Test batch parsing."""
parser = JSONParser()
lines = [
'{"level": "INFO", "message": "First"}',
'{"level": "ERROR", "message": "Second"}',
'{"level": "INFO", "message": "Third"}',
]
results = parser.parse_batch(lines)
assert len(results) == 3
assert results[0].message == "First"
assert results[1].message == "Second"
assert results[2].message == "Third"
class TestSyslogParser:
"""Tests for Syslog parser."""
def test_parse_rfc3164(self):
"""Test parsing RFC 3164 syslog format."""
parser = SyslogParser()
line = "Jan 15 10:30:00 server-01 app[1234]: Test message"
entry = parser.parse(line, 1)
assert entry is not None
assert entry.host == "server-01"
assert entry.logger == "app[1234]"
assert entry.message == "Test message"
def test_can_parse_syslog(self):
"""Test can_parse detection for syslog."""
parser = SyslogParser()
assert parser.can_parse("Jan 15 10:30:00 server-01 app: message")
assert parser.can_parse("<34>1 2024-01-15T10:30:00Z server-01 app - - - message")
assert not parser.can_parse("not syslog format")
def test_parse_priority(self):
"""Test parsing priority from syslog."""
parser = SyslogParser()
line = "<34>1 2024-01-15T10:30:00Z server-01 app - - - message"
entry = parser.parse(line, 1)
assert entry is not None
assert entry.facility == "auth"
class TestApacheParser:
"""Tests for Apache/Nginx parser."""
def test_parse_combined_log(self):
"""Test parsing Apache combined log format."""
parser = ApacheParser()
line = '192.168.1.1 - - [15/Jan/2024:10:30:00 +0000] "GET /api HTTP/1.1" 200 1234 "-" "Mozilla"'
entry = parser.parse(line, 1)
assert entry is not None
assert entry.host == "192.168.1.1"
assert entry.level == "info"
assert "GET /api" in entry.message
def test_can_parse_apache(self):
"""Test can_parse detection for Apache logs."""
parser = ApacheParser()
assert parser.can_parse('192.168.1.1 - - [15/Jan/2024:10:30:00 +0000] "GET /" 200 1234')
assert not parser.can_parse("not apache format")
def test_error_log(self):
"""Test parsing Apache error log."""
parser = ApacheParser()
line = '[Sat Jan 15 10:30:00.123456 2024] [mpm_prefork:notice] [pid 1234] AH00163: Apache configured'
entry = parser.parse(line, 1)
assert entry is not None
assert entry.level == "notice"
def test_status_code_inference(self):
"""Test severity inference from HTTP status codes."""
parser = ApacheParser()
entry_500 = parser.parse('192.168.1.1 - - [15/Jan/2024:10:30:00 +0000] "GET /" 500 123', 1)
assert entry_500.level == "error"
entry_404 = parser.parse('192.168.1.1 - - [15/Jan/2024:10:30:00 +0000] "GET /" 404 123', 1)
assert entry_404.level == "warning"
class TestParserFactory:
"""Tests for ParserFactory."""
def test_detect_json_format(self):
"""Test format detection for JSON logs."""
factory = ParserFactory()
line = '{"key": "value"}'
format_detected = factory.detect_format(line)
assert format_detected == LogFormat.JSON
def test_detect_syslog_format(self):
"""Test format detection for syslog."""
factory = ParserFactory()
line = "Jan 15 10:30:00 server-01 app: message"
format_detected = factory.detect_format(line)
assert format_detected == LogFormat.SYSLOG
def test_detect_apache_format(self):
"""Test format detection for Apache logs."""
factory = ParserFactory()
line = '192.168.1.1 - - [15/Jan/2024:10:30:00 +0000] "GET /" 200 123'
format_detected = factory.detect_format(line)
assert format_detected == LogFormat.APACHE
def test_parse_lines_with_auto_detection(self):
"""Test parsing lines with auto format detection."""
factory = ParserFactory()
lines = [
'{"level": "INFO", "message": "Test"}',
'{"level": "ERROR", "message": "Error test"}',
]
results = factory.parse_lines(lines)
assert len(results) == 2
def test_unknown_format(self):
"""Test handling of unknown format."""
factory = ParserFactory()
lines = ["not a known format"]
results = factory.parse_lines(lines)
assert len(results) == 1
assert results[0].message == "Unknown format"