[PATCH 4/6] binman: test: Fix code coverage for iMX8 and cst bintool
Simon Glass
sjg at chromium.org
Wed Feb 25 23:50:33 CET 2026
From: Simon Glass <simon.glass at canonical.com>
Three files are currently missing test coverage: nxp_imx8mcst,
nxp_imx8mimage and cst
Add test methods to cover all missing code paths, trying to reuse the
same .dts files where possible.
This brings all three files to 100% coverage.
Signed-off-by: Simon Glass <simon.glass at canonical.com>
---
tools/binman/ftest.py | 106 ++++++++++++++++++
tools/binman/test/339_nxp_imx8.dts | 3 +
tools/binman/test/364_nxp_imx8_csf.dts | 26 +++++
.../test/365_nxp_imx8_csf_fast_auth.dts | 21 ++++
tools/binman/test/366_nxp_imx8_imagename.dts | 27 +++++
5 files changed, 183 insertions(+)
create mode 100644 tools/binman/test/364_nxp_imx8_csf.dts
create mode 100644 tools/binman/test/365_nxp_imx8_csf_fast_auth.dts
create mode 100644 tools/binman/test/366_nxp_imx8_imagename.dts
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 276b0dd77fd..296de3dc218 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -7899,6 +7899,112 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
"""Test that binman can produce an iMX8 image"""
self._DoTestFile('339_nxp_imx8.dts')
+ def testNxpImx8ImageMissing(self):
+ """Test that binman produces an iMX8 image if mkimage is missing"""
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('339_nxp_imx8.dts',
+ force_missing_bintools='mkimage')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: mkimage")
+
+ def testNxpImx8ImagePos(self):
+ """Test SetImagePos for iMX8 image"""
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('339_nxp_imx8.dts', update_dtb=True,
+ force_missing_bintools='mkimage')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: mkimage")
+
+ def testNxpImx8mCSTNormal(self):
+ """Test CST signing with IVT-format input (normal auth, no unlock)"""
+ # Create fake IVT blob: magic(4) + padding(20) + signsize_addr(4)
+ # + padding(36) = 64 bytes
+ ivt_data = struct.pack('<I', 0x412000d1)
+ ivt_data += b'\x00' * 20
+ ivt_data += struct.pack('<I', 0)
+ ivt_data += b'\x00' * 36
+ self._MakeInputFile('imx8m-ivt.bin', ivt_data)
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('364_nxp_imx8_csf.dts',
+ force_missing_bintools='cst')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: cst")
+
+ def testNxpImx8mCSTFastAuth(self):
+ """Test CST signing with fast-auth mode, unlock, and FIT format"""
+ # FIT magic covers the FIT-signing path; fast-auth/unlock cover the
+ # ReadNode() and config-generation branches
+ fit_data = struct.pack('<I', 0xedfe0dd0)
+ fit_data += b'\x00' * 60
+ self._MakeInputFile('imx8m-fit.bin', fit_data)
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('365_nxp_imx8_csf_fast_auth.dts',
+ force_missing_bintools='cst')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: cst")
+
+ def testNxpImx8mCSTUnknownMagic(self):
+ """Test CST with unknown input magic passes data through"""
+ # Trigger the pass-through path use data with neither IVT nor FIT magic
+ data = b'\x00' * 64
+ self._MakeInputFile('imx8m-ivt.bin', data)
+ self._DoTestFile('364_nxp_imx8_csf.dts', force_missing_bintools='cst')
+
+ def testNxpImx8ImageSizeNone(self):
+ """Test SetImagePos() early return when an entry has no size"""
+ # The imagename entry is in GetEntries() but not packed, so has
+ # size=None, which triggers the early-return guard in SetImagePos()
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('366_nxp_imx8_imagename.dts',
+ force_missing_bintools='mkimage')
+
+ def testNxpImx8mCSTSigned(self):
+ """Test CST-signing-success path with mocked cst invocation"""
+ ivt_data = struct.pack('<I', 0x412000d1)
+ ivt_data += b'\x00' * 20
+ ivt_data += struct.pack('<I', 0)
+ ivt_data += b'\x00' * 36
+ self._MakeInputFile('imx8m-ivt.bin', ivt_data)
+
+ # Mock run_cmd() so that when cst is invoked, it creates a fake output
+ # blob and returns success, thus covering the signing path
+ original = bintool.Bintool.run_cmd
+
+ def fake_cst_run_cmd(self_tool, *args, binary=False):
+ if self_tool.name == 'cst':
+ arg_list = list(args)
+ if '-o' in arg_list:
+ idx = arg_list.index('-o')
+ tools.write_file(arg_list[idx + 1], b'\x00' * 32)
+ return 'fake cst output'
+ return original(self_tool, *args, binary=binary)
+
+ with unittest.mock.patch.object(bintool.Bintool, 'run_cmd',
+ new=fake_cst_run_cmd):
+ self._DoTestFile('364_nxp_imx8_csf.dts')
+
+ def testNxpImx8mCSTBintool(self):
+ """Test the cst bintool run() and fetch() methods"""
+ cst = bintool.Bintool.create('cst')
+ self.assertEqual('cst', cst.name)
+
+ # Mark cst as missing so run() exercises the code without needing the
+ # real tool (which fails without valid signing keys)
+ old_missing = bintool.Bintool.missing_list
+ bintool.Bintool.set_missing_list(['cst'])
+ try:
+ self.assertIsNone(cst.run('test.bin'))
+ finally:
+ bintool.Bintool.set_missing_list(old_missing)
+ # fetch() only supports FETCH_BUILD; other methods return None
+ self.assertIsNone(cst.fetch(bintool.FETCH_BIN))
+
+ # fetch(FETCH_BUILD) calls build_from_git() so mock it
+ with unittest.mock.patch.object(
+ bintool.Bintool, 'build_from_git', return_value=('cst', None)):
+ result = cst.fetch(bintool.FETCH_BUILD)
+ self.assertEqual(('cst', None), result)
+
def testNxpHeaderDdrfw(self):
"""Test that binman can add a header to DDR PHY firmware images"""
data = self._DoReadFile('353_nxp_ddrfw_imx95.dts')
diff --git a/tools/binman/test/339_nxp_imx8.dts b/tools/binman/test/339_nxp_imx8.dts
index cb512ae9aa2..d9fc86635b4 100644
--- a/tools/binman/test/339_nxp_imx8.dts
+++ b/tools/binman/test/339_nxp_imx8.dts
@@ -12,6 +12,9 @@
nxp,boot-from = "sd";
nxp,rom-version = <1>;
nxp,loader-address = <0x10>;
+
+ u-boot {
+ };
};
};
};
diff --git a/tools/binman/test/364_nxp_imx8_csf.dts b/tools/binman/test/364_nxp_imx8_csf.dts
new file mode 100644
index 00000000000..148f4668bb9
--- /dev/null
+++ b/tools/binman/test/364_nxp_imx8_csf.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mcst {
+ args;
+ nxp,loader-address = <0x10>;
+
+ blob {
+ filename = "imx8m-ivt.bin";
+ };
+
+ imagename {
+ type = "section";
+
+ u-boot {
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/365_nxp_imx8_csf_fast_auth.dts b/tools/binman/test/365_nxp_imx8_csf_fast_auth.dts
new file mode 100644
index 00000000000..af35f2569df
--- /dev/null
+++ b/tools/binman/test/365_nxp_imx8_csf_fast_auth.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mcst {
+ args;
+ nxp,loader-address = <0x10>;
+ nxp,fast-auth;
+ nxp,unlock;
+
+ blob {
+ filename = "imx8m-fit.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/366_nxp_imx8_imagename.dts b/tools/binman/test/366_nxp_imx8_imagename.dts
new file mode 100644
index 00000000000..58dd1ca3d5d
--- /dev/null
+++ b/tools/binman/test/366_nxp_imx8_imagename.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mimage {
+ args; /* TODO: Needed by mkimage etype superclass */
+ nxp,boot-from = "sd";
+ nxp,rom-version = <1>;
+ nxp,loader-address = <0x10>;
+
+ u-boot {
+ };
+
+ imagename {
+ type = "section";
+
+ u-boot {
+ };
+ };
+ };
+ };
+};
--
2.43.0
More information about the U-Boot
mailing list