fix(classifier): 🩹 avoid having multiple times the same line

This commit is contained in:
2026-09-22 17:46:57 +02:00
parent 369e7f17c6
commit 48181c97b8
2 changed files with 149 additions and 4 deletions
+108 -1
View File
@@ -6,7 +6,7 @@ import pytest
from logwatcher.classifier import N2_PATTERNS, classify_log_entries
from logwatcher.config import FIXTURE_PATH
from logwatcher.parser import parse_file
from logwatcher.parser import parse_file, parse_lines
def _pattern_name_to_filename(name: str) -> str:
@@ -118,3 +118,110 @@ def test_classify_log_entries_empty_log_entries(invalid_log_dir: Path):
relevant, irrelevant = classify_log_entries(log_entries)
assert not relevant and not irrelevant
N2_ERROR_MESSAGE = "Erreur : GetTvaId -> TVA non trouvée : 20,00"
OTHER_ERROR_MESSAGE = "Erreur FTP SDUpdatePrixISF : Requested action not taken"
def _build_log_line(
error_time: str,
error_message: str,
store_name: str = "GABRIEL",
start_time: str = "22/09/2026 09:28:58",
mdc_server_name: str = "MDC_220",
server_ip: str = "192.168.13.22",
) -> str:
"""Build a raw log line as written by a MDC scan."""
return (
f"\\\\{server_ip}\\e\\{mdc_server_name}\\Logs\\26\\09\\22\\20260922092847.txt "
f"[{start_time}] DOSSIER EN COURS : {store_name} "
f"[{error_time}] {error_message}"
)
def test_classify_log_entries_merges_consecutive_duplicates():
"""Consecutive identical errors become a single log entry."""
log_entries = parse_lines(
[
_build_log_line("22/09/2026 09:32:19", N2_ERROR_MESSAGE),
_build_log_line("22/09/2026 09:32:20", N2_ERROR_MESSAGE),
_build_log_line("22/09/2026 09:32:25", N2_ERROR_MESSAGE),
]
)
relevant, irrelevant = classify_log_entries(log_entries)
assert len(relevant) == 1
assert relevant[0].get_error_time() == "22/09/2026 09:32:19"
assert not irrelevant
def test_classify_log_entries_merges_same_error_name():
"""Same error code with a different amount is still a single log entry."""
log_entries = parse_lines(
[
_build_log_line(
"22/09/2026 09:32:19", "Erreur : GetTvaId -> TVA non trouvée : 8,50"
),
_build_log_line(
"22/09/2026 09:32:20", "Erreur : GetTvaId -> TVA non trouvée : 20,00"
),
]
)
relevant, _ = classify_log_entries(log_entries)
assert len(relevant) == 1
def test_classify_log_entries_keeps_duplicates_from_other_store_or_scan():
"""Same error from another scan or another store is not a duplicate."""
log_entries = parse_lines(
[
_build_log_line("22/09/2026 09:32:19", N2_ERROR_MESSAGE),
_build_log_line(
"22/09/2026 10:29:10",
N2_ERROR_MESSAGE,
start_time="22/09/2026 10:28:58",
),
_build_log_line(
"22/09/2026 09:32:19", N2_ERROR_MESSAGE, store_name="DUTOUR"
),
]
)
relevant, _ = classify_log_entries(log_entries)
assert len(relevant) == 3
def test_classify_log_entries_merges_consecutive_irrelevant_duplicates():
"""Deduplication also applies to errors that do not require N2 support."""
log_entries = parse_lines(
[
_build_log_line("22/09/2026 09:32:19", OTHER_ERROR_MESSAGE),
_build_log_line("22/09/2026 09:32:24", OTHER_ERROR_MESSAGE),
]
)
relevant, irrelevant = classify_log_entries(log_entries)
assert not relevant
assert len(irrelevant) == 1
def test_classify_log_entries_keeps_same_error_separated_by_another_error():
"""An interleaved error breaks the run, so both errors are kept."""
log_entries = parse_lines(
[
_build_log_line("22/09/2026 09:32:19", N2_ERROR_MESSAGE),
_build_log_line("22/09/2026 09:32:20", OTHER_ERROR_MESSAGE),
_build_log_line("22/09/2026 09:32:21", N2_ERROR_MESSAGE),
]
)
relevant, irrelevant = classify_log_entries(log_entries)
assert len(relevant) == 2
assert len(irrelevant) == 1