"""Unit tests for `jetson.tegrastats_parser`.""" from __future__ import annotations import io import json from pathlib import Path import pytest # Add jetson/ to path so the module is importable as a flat script. import sys JETSON_ROOT = Path(__file__).resolve().parents[2] / "jetson" if str(JETSON_ROOT) not in sys.path: sys.path.insert(0, str(JETSON_ROOT)) import tegrastats_parser # noqa: E402 SAMPLE_LINE = ( "11-21-2025 14:32:18 RAM 2345/7858MB (lfb 480x4MB) SWAP 0/0MB (cached 0MB) " "CPU [42%@1190,55%@1190,38%@1190,12%@729,off,off] EMC_FREQ 23%@665 " "GR3D_FREQ 67%@624 NVDEC off NVJPG off VIC_FREQ off APE 233 " "MTS fg 0% bg 1% AO@43.5C CPU@52.0C GPU@49.0C tj@52.0C VDD_IN 8200/8050 VDD_CPU 1500/1480 VDD_SOC 2300/2250 VDD_CV 1200/1180" ) def test_parse_line_extracts_ram() -> None: row = tegrastats_parser.parse_line(SAMPLE_LINE) assert row is not None assert row["ram_used_mb"] == "2345" assert row["ram_total_mb"] == "7858" def test_parse_line_extracts_gpu_load_and_freq() -> None: row = tegrastats_parser.parse_line(SAMPLE_LINE) assert row is not None assert row["gpu_load_pct"] == "67" assert row["gpu_freq_mhz"] == "624" def test_parse_line_extracts_temperatures() -> None: row = tegrastats_parser.parse_line(SAMPLE_LINE) assert row is not None # SOC temp pattern matches "AO@43.5C" via the case-insensitive SoC fallback, # but more importantly GPU@49.0C is matched. assert row["gpu_temp_c"] == "49.0" def test_parse_line_averages_cpu_loads() -> None: row = tegrastats_parser.parse_line(SAMPLE_LINE) assert row is not None # 42, 55, 38, 12 = avg 36.75 → "36.8" assert row["cpu_load_avg_pct"] == "36.8" def test_parse_line_blank_returns_none() -> None: assert tegrastats_parser.parse_line("") is None assert tegrastats_parser.parse_line(" \n") is None def test_parse_line_extras_json_round_trips() -> None: row = tegrastats_parser.parse_line(SAMPLE_LINE) assert row is not None extras = json.loads(str(row["extras_json"])) assert "raw" in extras def test_stream_to_csv_writes_expected_columns(tmp_path: Path) -> None: # Arrange source = io.StringIO("\n".join([SAMPLE_LINE, SAMPLE_LINE])) out_path = tmp_path / "tegrastats.csv" # Act n = tegrastats_parser.stream_to_csv(source, out_path) # Assert assert n == 2 text = out_path.read_text(encoding="utf-8") first_line = text.splitlines()[0] assert first_line == ",".join(tegrastats_parser.CSV_COLUMNS)