Files
MeshCore/test/test_ota_cold_buffers.py
T

61 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Verify real OTA cold allocations, host DATA cache ownership and streaming proofs.
The fixture uses controlled host representations, encoder/decoder callbacks and
radio admission. It validates manager bytes/hashes/proofs under sanitizers, not
the DEFLATE codec or physical USB/BLE/radio transport.
"""
from pathlib import Path
import os
import shutil
import subprocess
import tempfile
import unittest
from test_serial_wifi_sessions import SANITIZER_FLAGS
ROOT = Path(__file__).resolve().parents[1]
FIXTURE = ROOT / "test/fixtures/ota_cold_buffers/test.cpp"
HOST_MARKERS = (
"host compression needs leaves only; allocation denial and invalid-output fallback",
"host short tail and maximum leaf capacity retain original source bounds",
"host bytes stay pinned through DATA/PROOF backpressure and raw/compressed switches",
"host DATA reloads after successful interleaved inbound decoding",
"partial failed inbound decoder cannot leak into pinned host DATA",
"host DATA survives interleaved source growth, failure and rollover",
"caller-owned self-source encoder output remains separate and unallocated",
)
class OtaColdBufferTests(unittest.TestCase):
def test_proofs_allocation_failures_and_transfer_lifetimes(self):
compiler = os.environ.get("CXX") or shutil.which("g++") or shutil.which("clang++")
if not compiler:
self.skipTest("a host C++17 compiler is required")
for platform in ((), ("-DNRF52_PLATFORM=1",),
("-DNRF52_PLATFORM=1", "-DOTA_SD_STORE=1"),
("-DESP32_PLATFORM=1",)):
with self.subTest(platform=platform), tempfile.TemporaryDirectory(prefix="ota-cold-") as directory:
binary = Path(directory) / "cold-buffers"
sources = ("OtaManager.cpp", "OtaProtocol.cpp", "MotaContainer.cpp", "MerkleTree.cpp")
built = subprocess.run([
compiler, "-std=c++17", "-O1", "-Wall", "-Wextra", "-Werror",
"-Wno-unused-parameter", "-Wno-sign-compare", *SANITIZER_FLAGS, *platform,
"-I", str(ROOT / "src"), "-I", str(ROOT / "test/mocks"),
str(FIXTURE), *[str(ROOT / "src/helpers/ota" / name) for name in sources],
str(ROOT / "src/Utils.cpp"), "-Wl,--wrap=malloc", "-Wl,--wrap=free",
"-o", str(binary),
], capture_output=True, text=True, timeout=60)
self.assertEqual(built.returncode, 0, built.stdout + built.stderr)
checked = subprocess.run([str(binary)], capture_output=True, text=True, timeout=60)
self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr)
for marker in HOST_MARKERS:
self.assertEqual(checked.stdout.count("PASS: " + marker), 1, checked.stdout)
self.assertIn("PASS: streaming proofs and OTA cold-buffer lifetimes", checked.stdout)
print(f"\n[OTA cold buffers: {platform or 'portable'}]\n{checked.stdout}", flush=True)
if __name__ == "__main__":
unittest.main()