Technician tool v0.2

Imported from the Google Drive folder 004-technician_tool/v0.2.
This commit is contained in:
kkallas committed 2026-09-26 16:53:59 +02:00
1 parent e5a33a1c34
commit e8b72b743d
17 files changed
+2410 -283

No files matched your search

+23 -14
View File
@@ -2,7 +2,7 @@ from pathlib import Path
import pytest
from kota_tech.core.logline import LineFramer, LineKind, parse_line
from kota_tech.core.logline import LineFramer, LineKind, parse_line, split_glued
FIXTURES = sorted((Path(__file__).parent / "fixtures").glob("*.txt"))
@@ -39,27 +39,35 @@ def test_framer_splits_and_idle_flushes():
def test_framer_drops_stale_fragment_after_open():
f = LineFramer(drop_first_partial=True, now=0.0)
assert f.feed(b"current time as t", now=0.01) == []
assert f.feed(b"imestamp\r\nW (15899) DeviceStatus: RTC\r\n", now=0.02) == ["W (15899) DeviceStatus: RTC\r"]
# Real capture: stale FIFO tail released together with the next live line.
f = LineFramer(drop_first_partial=True)
got = f.feed(b"I (96) boot: 6 ota_1 OTA app 00 11 00340000"
b"W (19497) BME688: RTC is uninitialized\r\nI (19820) SEN66: x\r\n")
assert got == ["W (19497) BME688: RTC is uninitialized\r", "I (19820) SEN66: x\r"]
def test_framer_keeps_first_line_from_idle_board():
# Board was silent at open; the boot banner arriving later must survive.
f = LineFramer(drop_first_partial=True, now=0.0)
assert f.feed(b"", now=0.1) == []
assert f.feed(b"ESP-ROM:esp32s3-20210327\r\n", now=5.0) == ["ESP-ROM:esp32s3-20210327\r"]
# Board silent at open; the boot banner arriving later must survive.
f = LineFramer(drop_first_partial=True)
assert f.feed(b"ESP-ROM:esp32s3-20210327\r\n") == ["ESP-ROM:esp32s3-20210327\r"]
def test_framer_cancel_drop():
f = LineFramer(drop_first_partial=True, now=0.0)
f.cancel_drop()
assert f.feed(b"ESP-ROM:esp32s3\n", now=0.01) == ["ESP-ROM:esp32s3"]
def test_framer_keeps_complete_first_line():
f = LineFramer(drop_first_partial=True)
assert f.feed(b"W (1) A: complete\r\n") == ["W (1) A: complete\r"]
def test_framer_splits_interleaved_lines():
f = LineFramer()
assert f.feed(b"I (2302) chip[DL]: I (2302) chip[DL]: Posting event\n") == [
"I (2302) chip[DL]: ", "I (2302) chip[DL]: Posting event"]
assert f.feed(b"wifi:\x1b[0;32mI (5) X: y\n") == ["wifi:", "\x1b[0;32mI (5) X: y"]
def test_framer_tolerates_invalid_utf8():
f = LineFramer()
assert f.feed(b"\xff\xfeI (1) X: y\n") == ["��I (1) X: y"]
# Garbage in front of a log line is split off rather than corrupting it.
assert f.feed(b"\xff\xfeI (1) X: y\n") == ["��", "I (1) X: y"]
@pytest.mark.parametrize("path", FIXTURES, ids=lambda p: p.name)
@@ -79,6 +87,7 @@ def test_replay_sample_log_chunked_equals_whole(path):
@pytest.mark.parametrize("path", FIXTURES, ids=lambda p: p.name)
def test_replay_sample_log_parses(path):
lines = [parse_line(r) for r in LineFramer().feed(path.read_bytes())]
raw_errors = sum(1 for r in path.read_text("utf-8", "replace").splitlines() if r.startswith("E ("))
raw_parts = [p for r in path.read_text("utf-8", "replace").splitlines() for p in split_glued(r)]
raw_errors = sum(1 for p in raw_parts if p.startswith("E ("))
assert sum(1 for ln in lines if ln.level == "E") == raw_errors
assert raw_errors > 0