♻️refactor(parser): refactor parsing methods
This commit is contained in:
+44
-38
@@ -3,48 +3,50 @@ from pathlib import Path
|
||||
import pytest
|
||||
|
||||
from logwatcher.models import LogEntry
|
||||
from logwatcher.parser import parse_log_file, parse_log_line
|
||||
from logwatcher.parser import parse_file, parse_line
|
||||
|
||||
|
||||
@pytest.fixture(name="empty_log_file")
|
||||
def empty_log_file_fixture(invalid_log_dir: Path) -> Path:
|
||||
"""
|
||||
Path of an empty log file.
|
||||
Ensures the parser does not raise an exception
|
||||
and returns an empty list.
|
||||
Path of an empty log file.
|
||||
Ensures the parser does not raise an exception
|
||||
and returns an empty list.
|
||||
"""
|
||||
return invalid_log_dir / "empty_file.txt"
|
||||
|
||||
|
||||
@pytest.fixture(name="bad_log_file")
|
||||
def bad_log_file_fixture(invalid_log_dir: Path) -> Path:
|
||||
"""
|
||||
Path of a file containing only incorrectly formatted lines.
|
||||
Each line fails at a different point in LOG_PATTERN
|
||||
(invalid IP, missing timestamp, missing DOSSIER EN COURS, etc.).
|
||||
No LogEntry should be produced.
|
||||
Path of a file containing only incorrectly formatted lines.
|
||||
Each line fails at a different point in LOG_PATTERN
|
||||
(invalid IP, missing timestamp, missing DOSSIER EN COURS, etc.).
|
||||
No LogEntry should be produced.
|
||||
"""
|
||||
return invalid_log_dir / "bad_log_file.txt"
|
||||
|
||||
|
||||
@pytest.fixture(name="specific_logs")
|
||||
def specific_logs_fixture(valid_log_dir: Path) -> list[str]:
|
||||
"""
|
||||
Single log lines chosen to cover specific cases.
|
||||
Each line is structurally valid and must be parsed
|
||||
successfully. Used for unit tests of parse_log_line().
|
||||
Single log lines chosen to cover specific cases.
|
||||
Each line is structurally valid and must be parsed
|
||||
successfully. Used for unit tests of parse_line().
|
||||
"""
|
||||
log_file = valid_log_dir / "specific_logs.txt"
|
||||
with open(log_file, 'r') as file:
|
||||
with open(log_file, "r") as file:
|
||||
return file.readlines()
|
||||
|
||||
|
||||
def test_parse_log_line(specific_logs: list[str]):
|
||||
def test_parse_line(specific_logs: list[str]):
|
||||
"""
|
||||
Every structurally valid line produces a complete LogEntry.
|
||||
Ensures no required field is empty or None after parsing
|
||||
a line conforming to the LAME MDC format.
|
||||
Every structurally valid line produces a complete LogEntry.
|
||||
Ensures no required field is empty or None after parsing
|
||||
a line conforming to the LAME MDC format.
|
||||
"""
|
||||
for log_line in specific_logs:
|
||||
log_entry = parse_log_line(log_line)
|
||||
log_entry = parse_line(log_line)
|
||||
assert log_entry is not None
|
||||
assert log_entry.server_ip is not None
|
||||
assert log_entry.mdc_server_name is not None
|
||||
@@ -52,49 +54,53 @@ def test_parse_log_line(specific_logs: list[str]):
|
||||
assert log_entry.store_name is not None
|
||||
assert log_entry.error_time is not None
|
||||
assert log_entry.error_message is not None
|
||||
assert log_entry.raw_line != ''
|
||||
assert log_entry.raw_line != ""
|
||||
|
||||
|
||||
def test_parse_empty_log_line():
|
||||
"""
|
||||
An empty or structurally invalid line returns None.
|
||||
Covered cases:
|
||||
- Empty string.
|
||||
- Directory header (\"Répertoire scanné : \\\\...\").
|
||||
An empty or structurally invalid line returns None.
|
||||
Covered cases:
|
||||
- Empty string.
|
||||
- Directory header (\"Répertoire scanné : \\\\...\").
|
||||
"""
|
||||
log_entry = parse_log_line("")
|
||||
log_entry = parse_line("")
|
||||
assert not log_entry
|
||||
|
||||
log_entry = parse_log_line("Répertoire scanné : \\\\192.168.60.48\\e$\\MDC_9110\\Logs")
|
||||
log_entry = parse_line("Répertoire scanné : \\\\192.168.60.48\\e$\\MDC_9110\\Logs")
|
||||
assert not log_entry
|
||||
|
||||
|
||||
def test_parse_valid_log_file(original_log_dir: Path):
|
||||
"""
|
||||
Each real log file produces at least one valid LogEntry.
|
||||
Integration test: files provided by technicians contain
|
||||
a mix of valid lines and lines to be ignored.
|
||||
Ensures the parser extracts at least one entry per file.
|
||||
Each real log file produces at least one valid LogEntry.
|
||||
Integration test: files provided by technicians contain
|
||||
a mix of valid lines and lines to be ignored.
|
||||
Ensures the parser extracts at least one entry per file.
|
||||
"""
|
||||
for log_file in original_log_dir.glob("CR_*"):
|
||||
log_list = parse_log_file(log_file)
|
||||
log_list = parse_file(log_file)
|
||||
assert len(log_list) > 0
|
||||
|
||||
for log_entry in log_list:
|
||||
assert isinstance(log_entry, LogEntry)
|
||||
|
||||
|
||||
def test_parse_empty_log_file(empty_log_file):
|
||||
"""
|
||||
An empty log file can be parsed and must returns an
|
||||
empty LogEntry list.
|
||||
An empty log file can be parsed and must returns an
|
||||
empty LogEntry list.
|
||||
"""
|
||||
log_list = parse_log_file(empty_log_file)
|
||||
log_list = parse_file(empty_log_file)
|
||||
assert len(log_list) == 0
|
||||
|
||||
|
||||
def test_parse_bad_log_file(bad_log_file):
|
||||
"""
|
||||
A file containing only invalid lines produces nothing.
|
||||
Any line that does not match the LAME MDC structure
|
||||
(IP, timestamps, DOSSIER EN COURS, error message)
|
||||
must be silently ignored.
|
||||
A file containing only invalid lines produces nothing.
|
||||
Any line that does not match the LAME MDC structure
|
||||
(IP, timestamps, DOSSIER EN COURS, error message)
|
||||
must be silently ignored.
|
||||
"""
|
||||
log_list = parse_log_file(bad_log_file)
|
||||
assert len(log_list) == 0
|
||||
log_list = parse_file(bad_log_file)
|
||||
assert len(log_list) == 0
|
||||
|
||||
Reference in New Issue
Block a user