Files
MeshCore/test/test_nrf52_endf_hex.py

94 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""Exercise the nRF52 HEX post-build hook with the installed build dependencies."""
from contextlib import redirect_stdout
import importlib.util
import io
from pathlib import Path
import sys
import tempfile
import unittest
from intelhex import IntelHex
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "tools" / "mota"))
import motalib as ml # noqa: E402
class BuildEnvironment(dict):
def __init__(self, app_base):
super().__init__(
PROJECT_DIR=str(ROOT),
PIOENV="nrf52_sensor_hex_test",
CPPDEFINES=[
"ENABLE_OTA", "NRF52_PLATFORM",
("FIRMWARE_VERSION", "v1.17.1.9"),
("MOTA_TARGET_ID", "0x12345678"),
("MOTA_HW_ID", "NRF52_TEST"),
],
)
self.app_base = app_base
self.post_actions = {}
def AddPostAction(self, target, action):
self.post_actions[target] = action
def BoardConfig(self):
return {"upload.maximum_size": ml.NRF52_APP_END - self.app_base}
def GetProjectOption(self, name, default=""):
if name in ("build_src_filter", "src_filter"):
return "+<examples/simple_sensor>"
return default
class Nrf52EndfHexTests(unittest.TestCase):
def test_hex_hook_appends_valid_identity_and_preserves_other_segments(self):
for app_base in (ml.NRF52_APP_BASE_S140_V6, ml.NRF52_APP_BASE_S140_V7):
with self.subTest(app_base=hex(app_base)), tempfile.TemporaryDirectory() as tmp:
env = BuildEnvironment(app_base)
spec = importlib.util.spec_from_file_location(
"nrf52_endf_hex_test", ROOT / "tools" / "mota" / "pio_endf.py")
module = importlib.util.module_from_spec(spec)
module.Import = lambda _name: None
module.env = env
spec.loader.exec_module(module)
action = env.post_actions["$BUILD_DIR/${PROGNAME}.hex"]
path = Path(tmp) / "firmware.hex"
firmware = bytes(range(256))
uicr_base = 0x10001080
uicr = b"\x12\x34\x56\x78"
original = IntelHex()
original.frombytes(firmware, offset=app_base)
original.frombytes(uicr, offset=uicr_base)
original.write_hex_file(str(path))
with redirect_stdout(io.StringIO()):
action([], [path], env)
result = IntelHex(str(path))
segments = result.segments()
self.assertEqual(len(segments), 2)
self.assertEqual(segments[0], (
app_base, app_base + len(firmware) + ml.NRF52_LAYOUT_LEN + ml.ENDF_LEN))
image = bytes(result.tobinarray(start=app_base, end=segments[0][1] - 1))
self.assertEqual(image[:len(firmware)], firmware)
self.assertEqual(bytes(result.tobinarray(
start=uicr_base, size=len(uicr))), uicr)
self.assertTrue(ml.has_endf(image))
self.assertEqual(ml.parse_endf_ident(image), ml.FwIdent(
ml.pack_version("1.17.1.9"), 0x12345678, "NRF52_TEST"))
self.assertEqual(ml.parse_nrf52_layout(image), ml.Nrf52Layout(
app_base, ml.NRF52_APP_END, ml.NRF52_APP_END))
first_pass = path.read_bytes()
with redirect_stdout(io.StringIO()):
action([], [path], env)
self.assertEqual(path.read_bytes(), first_pass)
if __name__ == "__main__":
unittest.main()