diff options
| author | Aristo Chen <aristo.chen@canonical.com> | 2026-08-18 13:23:18 +0000 |
|---|---|---|
| committer | Tom Rini <trini@konsulko.com> | 2026-09-01 15:10:29 -0600 |
| commit | 6b88aee1dd076e2e2091b47ac2fb9fc5f31a3353 (patch) | |
| tree | c21c3c7087a5b04ec10c0570627ed59d14ba5683 | |
| parent | 894eff92ecf060ec7363b9be41958e49ea120cab (diff) | |
| download | u-boot-6b88aee1dd076e2e2091b47ac2fb9fc5f31a3353.tar.gz u-boot-6b88aee1dd076e2e2091b47ac2fb9fc5f31a3353.zip | |
test: fit: cover the kernel_noload zstd header-size path
Parametrise NOLOAD_ITS on the compression field so a single template
can drive gzip, zstd, and future format tests, and update the
existing gzip callers to pass compression='gzip'.
Add test_fit_kernel_noload_decomp_zstd_hdr_sized: a 6 MiB payload
whose zstd compression ratio is past the 8x heuristic decompresses
cleanly because Frame_Content_Size is consulted. The test is guarded
by @pytest.mark.requiredtool('zstd') so it skips on hosts that do
not ship the zstd command.
Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
| -rwxr-xr-x | test/py/tests/test_fit.py | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py index 81df84f54c9..f59010c8c35 100755 --- a/test/py/tests/test_fit.py +++ b/test/py/tests/test_fit.py @@ -119,8 +119,9 @@ host save hostfs 0 %(loadables2_addr)x %(loadables2_out)s %(loadables2_size)x # A minimal ITS for a compressed 'kernel_noload' kernel. bootm allocates a # per-image decompression buffer for this image type, sized either from the -# gzip ISIZE trailer or as a multiple of the compressed length; see the -# test_fit_kernel_noload_decomp_* tests. +# compressor header (gzip ISIZE, zstd Frame_Content_Size, ...) or as a +# multiple of the compressed length; see the test_fit_kernel_noload_decomp_* +# tests. NOLOAD_ITS = ''' /dts-v1/; @@ -134,7 +135,7 @@ NOLOAD_ITS = ''' type = "kernel_noload"; arch = "sandbox"; os = "linux"; - compression = "gzip"; + compression = "%(compression)s"; load = <0>; entry = <0>; }; @@ -544,7 +545,7 @@ class TestFitImage: fd.write((256).to_bytes(4, 'little')) fit = fit_util.make_fit(ubman, fsetup['mkimage'], NOLOAD_ITS, - {'kernel': kernel_gz}) + {'kernel': kernel_gz, 'compression': 'gzip'}) fit_addr = fsetup['fit_addr'] ubman.run_command_list([ @@ -594,7 +595,7 @@ class TestFitImage: 'the test needs a bigger payload' % (heuristic_bound, decomp_size)) fit = fit_util.make_fit(ubman, fsetup['mkimage'], NOLOAD_ITS, - {'kernel': kernel_gz}, + {'kernel': kernel_gz, 'compression': 'gzip'}, basename='test-noload-hdrsized.fit') fit_addr = fsetup['fit_addr'] @@ -610,6 +611,52 @@ class TestFitImage: 'bootm rejected a well-compressed kernel_noload image whose ' 'ISIZE trailer records the real uncompressed size: %s' % text) + @pytest.mark.buildconfigspec('zstd') + @pytest.mark.requiredtool('zstd') + def test_fit_kernel_noload_decomp_zstd_hdr_sized(self, ubman, fsetup): + """A well-compressed zstd kernel_noload image fits when the frame + header carries Frame_Content_Size. + + Same as test_fit_kernel_noload_decomp_gzip_hdr_sized but for zstd. + The default zstd encoder embeds Frame_Content_Size for a + single-segment frame, so bootm can read it and size the buffer + accordingly. + """ + 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-zstd.bin') + with open(kernel, 'wb') as fd: + fd.write(b'\0' * decomp_size) + kernel_zstd = kernel + '.zst' + utils.run_and_log(ubman, ['zstd', '-f', kernel, '-o', kernel_zstd]) + + image_len = self.filesize(kernel_zstd) + 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, zstd 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_zstd, 'compression': 'zstd'}, + basename='test-noload-zstd-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 zstd kernel_noload image whose ' + 'frame header records the real content size: %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 @@ -637,7 +684,7 @@ class TestFitImage: % (decomp_size, req_size)) fit = fit_util.make_fit(ubman, fsetup['mkimage'], NOLOAD_ITS, - {'kernel': kernel_gz}, + {'kernel': kernel_gz, 'compression': 'gzip'}, basename='test-noload-boundary.fit') fit_addr = fsetup['fit_addr'] |
