diff options
| author | Simon Glass <[email protected]> | 2026-03-06 11:12:48 -0700 |
|---|---|---|
| committer | Simon Glass <[email protected]> | 2026-03-18 06:14:16 -0600 |
| commit | 0cab35362d7720975e7869d2bc3cc23cec73b376 (patch) | |
| tree | 2008dfc541d82a9597faeed2ece2759b9c73bcf1 /tools | |
| parent | b12f4bcf267c0eb80ef193f0eff246971812c575 (diff) | |
binman: test: Fix code coverage for iMX8 and cst bintool
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 <[email protected]>
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/binman/ftest.py | 106 | ||||
| -rw-r--r-- | tools/binman/test/vendor/nxp_imx8.dts | 3 | ||||
| -rw-r--r-- | tools/binman/test/vendor/nxp_imx8_csf.dts | 26 | ||||
| -rw-r--r-- | tools/binman/test/vendor/nxp_imx8_csf_fast_auth.dts | 21 | ||||
| -rw-r--r-- | tools/binman/test/vendor/nxp_imx8_imagename.dts | 27 |
5 files changed, 183 insertions, 0 deletions
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 612237d0b41..9cc1a97f95c 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('vendor/nxp_imx8.dts') + def testNxpImx8ImageMissing(self): + """Test that binman produces an iMX8 image if mkimage is missing""" + with terminal.capture() as (_, stderr): + self._DoTestFile('vendor/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('vendor/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('vendor/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('vendor/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('vendor/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('vendor/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('vendor/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('vendor/nxp_ddrfw_imx95.dts') diff --git a/tools/binman/test/vendor/nxp_imx8.dts b/tools/binman/test/vendor/nxp_imx8.dts index cb512ae9aa2..d9fc86635b4 100644 --- a/tools/binman/test/vendor/nxp_imx8.dts +++ b/tools/binman/test/vendor/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/vendor/nxp_imx8_csf.dts b/tools/binman/test/vendor/nxp_imx8_csf.dts new file mode 100644 index 00000000000..148f4668bb9 --- /dev/null +++ b/tools/binman/test/vendor/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/vendor/nxp_imx8_csf_fast_auth.dts b/tools/binman/test/vendor/nxp_imx8_csf_fast_auth.dts new file mode 100644 index 00000000000..af35f2569df --- /dev/null +++ b/tools/binman/test/vendor/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/vendor/nxp_imx8_imagename.dts b/tools/binman/test/vendor/nxp_imx8_imagename.dts new file mode 100644 index 00000000000..58dd1ca3d5d --- /dev/null +++ b/tools/binman/test/vendor/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 { + }; + }; + }; + }; +}; |
