summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAristo Chen <aristo.chen@canonical.com>2026-08-18 13:23:22 +0000
committerTom Rini <trini@konsulko.com>2026-09-01 15:10:29 -0600
commit6bd934a1f5e9f37579af123d49114aee35607449 (patch)
tree51582aa0525ab26598e8f8b8289138e1a9ac7427
parenta730ba7f8996468e04250ce182a8bceaf30cb78c (diff)
downloadu-boot-6bd934a1f5e9f37579af123d49114aee35607449.tar.gz
u-boot-6bd934a1f5e9f37579af123d49114aee35607449.zip
test: fit: cover the kernel_noload lzma header-size and unknown-size paths
Exercise bootm_lzma_uncompressed_size() end-to-end on sandbox: - test_fit_kernel_noload_decomp_lzma_hdr_sized boots a 6 MiB kernel_noload payload that lzma compresses far past the 8x fallback heuristic, so the boot only succeeds when bootm sizes the buffer from the header's uncompressed-size field. Streaming encoders write the "unknown" marker into that field, so the test compresses with Python's lzma module and patches the real size into the fixed 8-byte field, matching what LZMA SDK style encoders record. - test_fit_kernel_noload_decomp_lzma_unknown_size leaves the marker in place and checks that bootm falls back to the 8x heuristic buffer and still boots the image. No external tool is required: Python's lzma module is part of the standard library. Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
-rwxr-xr-xtest/py/tests/test_fit.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py
index 42edddb0600..0edf875a9e1 100755
--- a/test/py/tests/test_fit.py
+++ b/test/py/tests/test_fit.py
@@ -704,6 +704,104 @@ class TestFitImage:
'bootm rejected a well-compressed zstd kernel_noload image whose '
'frame header records the real content size: %s' % text)
+ @pytest.mark.buildconfigspec('lzma')
+ def test_fit_kernel_noload_decomp_lzma_hdr_sized(self, ubman, fsetup):
+ """A well-compressed lzma kernel_noload image fits when the header
+ records the real uncompressed size.
+
+ Same as test_fit_kernel_noload_decomp_gzip_hdr_sized but for lzma.
+ Streaming encoders write the "unknown" marker into the .lzma-alone
+ size field, so compress with Python's lzma module and patch the
+ real size into the fixed 8-byte header field, the way LZMA SDK
+ style encoders record it.
+ """
+ lzma = pytest.importorskip('lzma')
+ sz_1m = 1 << 20
+ bootm_len = int(ubman.config.buildconfig['config_sys_bootm_len'], 0)
+
+ decomp_size = 6 * sz_1m
+ assert decomp_size <= bootm_len, (
+ 'Test setup error: decomp_size (%#x) must be <= '
+ 'CONFIG_SYS_BOOTM_LEN (%#x)' % (decomp_size, bootm_len))
+ kernel = fit_util.make_fname(ubman, 'test-noload-kernel-lzma.bin')
+ with open(kernel, 'wb') as fd:
+ fd.write(b'\0' * decomp_size)
+ filters = [{'id': lzma.FILTER_LZMA1, 'preset': 6,
+ 'dict_size': 1 << 20}]
+ blob = lzma.compress(self.read_file(kernel),
+ format=lzma.FORMAT_ALONE, filters=filters)
+ assert blob[5:13] == b'\xff' * 8, (
+ 'Test setup error: expected the streaming encoder to write the '
+ '"unknown" size marker')
+ blob = blob[:5] + decomp_size.to_bytes(8, 'little') + blob[13:]
+ kernel_lzma = kernel + '.lzma'
+ with open(kernel_lzma, 'wb') as fd:
+ fd.write(blob)
+
+ image_len = self.filesize(kernel_lzma)
+ heuristic_bound = (image_len * 8 + sz_1m - 1) // sz_1m * sz_1m
+ assert heuristic_bound < decomp_size, (
+ 'Test setup error: 8x heuristic bound (%#x) must be < uncompressed '
+ 'size (%#x); if this fires, lzma got less effective and the test '
+ 'needs a bigger payload' % (heuristic_bound, decomp_size))
+
+ fit = fit_util.make_fit(ubman, fsetup['mkimage'], NOLOAD_ITS,
+ {'kernel': kernel_lzma, 'compression': 'lzma'},
+ basename='test-noload-lzma-hdrsized.fit')
+ fit_addr = fsetup['fit_addr']
+
+ output = ubman.run_command_list([
+ 'host load hostfs 0 %x %s' % (fit_addr, fit),
+ 'bootm start %x' % fit_addr,
+ 'bootm loados',
+ ])
+ text = '\n'.join(output)
+ assert 'Image too large' not in text, (
+ 'bootm rejected a well-compressed lzma kernel_noload image whose '
+ 'header records the real uncompressed size: %s' % text)
+
+ @pytest.mark.buildconfigspec('lzma')
+ def test_fit_kernel_noload_decomp_lzma_unknown_size(self, ubman, fsetup):
+ """An lzma stream with the "unknown" size marker falls back cleanly
+
+ Streaming encoders write 0xff..ff into the .lzma-alone size field.
+ bootm must fall back to the 8x heuristic buffer and still boot the
+ image.
+ """
+ lzma = pytest.importorskip('lzma')
+ sz_1m = 1 << 20
+
+ # Incompressible data keeps the real size well inside the 8x
+ # fallback buffer.
+ payload = os.urandom(sz_1m)
+ kernel = fit_util.make_fname(ubman, 'test-noload-kernel-lzma-unk.bin')
+ filters = [{'id': lzma.FILTER_LZMA1, 'preset': 6,
+ 'dict_size': 1 << 20}]
+ blob = lzma.compress(payload, format=lzma.FORMAT_ALONE,
+ filters=filters)
+ assert blob[5:13] == b'\xff' * 8, (
+ 'Test setup error: expected the streaming encoder to write the '
+ '"unknown" size marker')
+ kernel_lzma = kernel + '.lzma'
+ with open(kernel_lzma, 'wb') as fd:
+ fd.write(blob)
+
+ fit = fit_util.make_fit(ubman, fsetup['mkimage'], NOLOAD_ITS,
+ {'kernel': kernel_lzma, 'compression': 'lzma'},
+ basename='test-noload-lzma-unk.fit')
+ fit_addr = fsetup['fit_addr']
+
+ output = ubman.run_command_list([
+ 'host load hostfs 0 %x %s' % (fit_addr, fit),
+ 'bootm start %x' % fit_addr,
+ 'bootm loados',
+ ])
+ text = '\n'.join(output)
+ assert 'Image too large' not in text, (
+ 'bootm rejected an lzma kernel_noload image carrying the '
+ '"unknown" size marker; the 8x fallback should have covered '
+ 'it: %s' % text)
+
@pytest.mark.buildconfigspec('gzip')
def test_fit_kernel_noload_decomp_gzip_boundary(self, ubman, fsetup):
"""Test that decompression succeeds exactly at the buffer limit