Files
MeshCore/test/test_host_kiss_ram.py
T

80 lines
4.9 KiB
Python

#!/usr/bin/env python3
"""Bind the optional KISS heap allowance to the real codec and ELF gate."""
import contextlib
import io
import json
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
ROOT=Path(__file__).resolve().parents[1]
sys.path.insert(0,str(ROOT/"scripts"))
import check_firmware_ram as ram
from test_firmware_ram import elf32,esp_fixture
class HostKissRamTest(unittest.TestCase):
def test_enabled_codec_adds_two_kib_without_lowering_other_reserves(self):
for platform in ("ESP32_PLATFORM","NRF52_PLATFORM"):
for target in ("board_companion_radio_full","board_repeater","board_room_server","board_sensor"):
with self.subTest(platform=platform,target=target):
flags={"BLE_PIN_CODE":123456}
off=ram.requirements(platform,{**flags,"MESH_ENABLE_HOST_KISS":0},target)
on=ram.requirements(platform,{**flags,"MESH_ENABLE_HOST_KISS":1},target)
self.assertEqual(on["components"]["host_kiss_codec"],2048)
self.assertEqual(on["required_heap_bytes"],off["required_heap_bytes"]+2048)
self.assertEqual({key:value for key,value in on["components"].items()
if key!="host_kiss_codec"},off["components"])
self.assertEqual(on["required_contiguous_bytes"],off["required_contiguous_bytes"])
default=ram.requirements(platform,{**flags,"COMPANION_RADIO_FULL":1},target)
self.assertEqual(default["components"],on["components"])
for extra in ({"COMPANION_RADIO_FULL":0},
{"COMPANION_RADIO_FULL":1,"MESH_ENABLE_HOST_KISS":0},
{"MESH_ENABLE_HOST_KISS":1,"MESH_PRIMARY_ESPNOW":1}):
self.assertEqual(ram.requirements(platform,{**flags,**extra},target)["components"],off["components"])
for platform in ("STM32_PLATFORM","RP2040_PLATFORM"):
self.assertEqual(ram.requirements(platform,{"MESH_ENABLE_HOST_KISS":1},"board_companion_radio_ble"),
ram.requirements(platform,{},"board_companion_radio_ble"))
def test_real_elf_rejects_unbudgeted_codec_and_honors_exact_new_boundary(self):
for platform in ("ESP32_PLATFORM","NRF52_PLATFORM"):
with self.subTest(platform=platform),tempfile.TemporaryDirectory() as folder:
folder=Path(folder);path=folder/"firmware.elf";report=folder/"memory.json"
target="board_companion_radio_full"
flags={"COMPANION_RADIO_FULL":1,"MESH_ENABLE_HOST_KISS":1,"BLE_PIN_CODE":123456}
required=ram.requirements(platform,flags,target)["required_heap_bytes"]
old=ram.requirements(platform,{**flags,"MESH_ENABLE_HOST_KISS":0},target)["required_heap_bytes"]
self.assertEqual(required,old+2048)
for available,accepted in ((old,False),(required-1,False),(required,True)):
with self.subTest(available=available),contextlib.redirect_stdout(io.StringIO()),contextlib.redirect_stderr(io.StringIO()):
if platform=="ESP32_PLATFORM":
esp_fixture(path,internal_length=available-0x10000+0x4000)
else:
elf32(path,{"__HeapBase":(0x20010000,0),"__HeapLimit":(0x20010000+available,0)})
status=ram.check_firmware(path,platform,"esp32" if platform=="ESP32_PLATFORM" else "nrf52840",flags,target,report)
actual=json.loads(report.read_text())
self.assertEqual(status==0,accepted)
self.assertEqual(actual["required_heap_bytes"],required)
self.assertEqual(actual["components"]["host_kiss_codec"],2048)
def test_actual_codec_size_is_source_bounded_and_queue_growth_fails(self):
source=(ROOT/"src/helpers/HostKissCodec.h").read_text()
with tempfile.TemporaryDirectory() as folder:
folder=Path(folder);header=folder/"Codec.h";main=folder/"main.cpp";binary=folder/"test"
main.write_text('#include "Codec.h"\n#include <stdio.h>\nint main(){printf("%zu\\n",sizeof(mesh::hostkiss::Codec));}\n')
for changed,accepted in ((source,True),(source.replace("QueueDepth = 2","QueueDepth = 3"),False)):
header.write_text(changed)
result=subprocess.run(["g++","-std=c++17",str(main),"-o",str(binary)],capture_output=True,text=True)
self.assertEqual(result.returncode==0,accepted,result.stdout+result.stderr)
if accepted:
size=int(subprocess.check_output([str(binary)]))
self.assertEqual(size,1828)
self.assertLessEqual(size+32,2048)
else:
self.assertIn("runtime RAM allowance",result.stderr)
if __name__=="__main__":unittest.main()