feat: parse and validate FIT containers

This commit is contained in:
Bastian Wagner
2026-08-15 10:27:05 +02:00
parent 4599b2b71c
commit a47ad77071
4 changed files with 212 additions and 0 deletions

32
tests/fit/builders.py Normal file
View File

@@ -0,0 +1,32 @@
import struct
from app.fit.crc import fit_crc
def make_fit(data_records: bytes, *, header_size: int = 14) -> bytes:
if header_size not in {12, 14}:
raise ValueError(header_size)
header = bytearray(header_size)
header[0] = header_size
header[1] = 0x20
struct.pack_into("<H", header, 2, 0x0100)
struct.pack_into("<I", header, 4, len(data_records))
header[8:12] = b".FIT"
if header_size == 14:
struct.pack_into("<H", header, 12, fit_crc(header[:12]))
body = header + data_records
return bytes(body + struct.pack("<H", fit_crc(body)))
def definition(local: int, global_num: int, fields: list[tuple[int, int, int]], *, endian: str = "<") -> bytes:
architecture = 1 if endian == ">" else 0
payload = bytearray([0, architecture])
payload.extend(struct.pack(f"{endian}H", global_num))
payload.append(len(fields))
for num, size, base_type in fields:
payload.extend(bytes([num, size, base_type]))
return bytes([0x40 | local]) + bytes(payload)
def data(local: int, payload: bytes) -> bytes:
return bytes([local]) + payload

View File

@@ -0,0 +1,21 @@
from pathlib import Path
import pytest
from app.fit.rewriter import FitFormatError, is_fit_file
from tests.fit.builders import make_fit
def test_valid_12_and_14_byte_headers(tmp_path: Path) -> None:
for size in (12, 14):
path = tmp_path / f"valid-{size}.fit"
path.write_bytes(make_fit(b"", header_size=size))
assert is_fit_file(path) is True
def test_bad_file_crc_is_rejected(tmp_path: Path) -> None:
payload = bytearray(make_fit(b""))
payload[-1] ^= 0xFF
path = tmp_path / "bad.fit"
path.write_bytes(payload)
assert is_fit_file(path) is False