from __future__ import annotations from pathlib import Path from app.executors.log_executor import GrepLogExecutor def test_grep_log_executor_matches_keyword(tmp_path: Path) -> None: log_file = tmp_path / "app.log" log_file.write_text("INFO start\nERROR failed to boot\nINFO done\n", encoding="utf-8") success, message, data, evidence = GrepLogExecutor().execute( { "path": str(log_file), "keyword": "ERROR", "limit": 10, } ) assert success is True assert message == "keyword matched" assert data["matched_count"] == 1 assert evidence["matches"][0]["line_number"] == 2 def test_grep_log_executor_missing_file() -> None: success, message, data, evidence = GrepLogExecutor().execute( { "path": "not-exists.log", "keyword": "ERROR", } ) assert success is False assert "not found" in message assert data == {} assert evidence == {} def test_grep_log_executor_filters_by_time_range(tmp_path: Path) -> None: log_file = tmp_path / "timed.log" log_file.write_text( "\n".join( [ "2026-04-09 10:00:00.000 INFO start", "2026-04-09 10:05:00.000 ERROR first failure", "2026-04-09 10:10:00.000 ERROR second failure", ] ) + "\n", encoding="utf-8", ) success, message, data, evidence = GrepLogExecutor().execute( { "path": str(log_file), "keyword": "ERROR", "start_at": "2026-04-09 10:06:00.000", "end_at": "2026-04-09 10:11:00.000", } ) assert success is True assert message == "keyword matched" assert data["matched_count"] == 1 assert evidence["matches"][0]["line_number"] == 3