79 lines
3.5 KiB
Python
79 lines
3.5 KiB
Python
"""Exercise the production raw-BIN post hook and ordered identity overrides."""
|
|
import os
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
|
|
from test_nrf52_endf_hex import BuildEnvironment, load_post_script, ml, stamp
|
|
|
|
|
|
class EndfRestampTests(unittest.TestCase):
|
|
def environment(self):
|
|
env = BuildEnvironment(ml.NRF52_APP_BASE_S140_V7)
|
|
env["PIOENV"] = "esp32_restamp_test"
|
|
env["CPPDEFINES"].remove("NRF52_PLATFORM")
|
|
return env
|
|
|
|
def test_bin_restamps_identity_without_length_growth_or_same_size_write_omission(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
env = self.environment()
|
|
load_post_script(env)
|
|
action = env.post_actions["$BUILD_DIR/${PROGNAME}.bin"]
|
|
path = Path(directory) / "firmware.bin"
|
|
body = b"\xe9" + bytes(range(255))
|
|
path.write_bytes(body)
|
|
stamp(action, path, env)
|
|
for index in range(3):
|
|
env["CPPDEFINES"].extend([
|
|
("FIRMWARE_VERSION", f"v1.17.1.{10 + index}"),
|
|
("MOTA_TARGET_ID", hex(0x87654321 + index)),
|
|
("MOTA_HW_ID", f"CHANGED_{index}"),
|
|
])
|
|
stamp(action, path, env)
|
|
stamped = path.read_bytes()
|
|
self.assertEqual(len(stamped), len(body) + ml.ENDF_LEN)
|
|
self.assertEqual(ml.parse_endf(stamped)[0], body)
|
|
self.assertEqual(stamped.count(ml.ENDF_MAGIC), 1)
|
|
self.assertEqual(ml.parse_endf_ident(stamped), ml.FwIdent(
|
|
ml.pack_version(f"1.17.1.{10 + index}"),
|
|
0x87654321 + index, f"CHANGED_{index}"))
|
|
os.utime(path, ns=(1_000_000_000, 1_000_000_000))
|
|
stamp(action, path, env)
|
|
self.assertEqual(path.read_bytes(), stamped)
|
|
self.assertEqual(path.stat().st_mtime_ns, 1_000_000_000)
|
|
|
|
def test_cppdef_last_matching_tuple_list_or_bare_define_wins(self):
|
|
env = self.environment()
|
|
module = load_post_script(env)
|
|
cases = (([("VALUE", "old"), ("VALUE", "new")], "new"),
|
|
([("VALUE", "old"), ["VALUE", 123]], "123"),
|
|
([("VALUE", "old"), "VALUE"], ""),
|
|
(["VALUE", ("VALUE", "new")], "new"),
|
|
([("VALUE", "old"), ("VALUE",)], ""),
|
|
([("OTHER", 123)], None))
|
|
for defines, expected in cases:
|
|
with self.subTest(defines=defines):
|
|
env["CPPDEFINES"] = defines
|
|
self.assertEqual(module._cppdef("VALUE"), expected)
|
|
|
|
def test_general_ensure_endf_retains_its_existing_preserve_identity_contract(self):
|
|
image, _ = ml.ensure_endf(b"body", ml.FwIdent(1, 2, "ORIGINAL"))
|
|
self.assertEqual(ml.ensure_endf(image, ml.FwIdent(3, 4, "OTHER"))[0], image)
|
|
|
|
def test_a_freshly_relinked_body_receives_its_own_current_hash(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
env = self.environment()
|
|
load_post_script(env)
|
|
action = env.post_actions["$BUILD_DIR/${PROGNAME}.bin"]
|
|
path = Path(directory) / "firmware.bin"
|
|
for body in (b"\xe9old app", b"\xe9new app, relinked without an old trailer"):
|
|
path.write_bytes(body)
|
|
stamp(action, path, env)
|
|
parsed_body, hash8 = ml.parse_endf(path.read_bytes())
|
|
self.assertEqual(parsed_body, body)
|
|
self.assertEqual(hash8, ml.mh8(body))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|