test_fit

Sanity check of the FIT handling in U-Boot

class test_fit.TestFitImage

Test class for FIT image handling in U-Boot

TODO: Almost everything:
  • hash algorithms - invalid hash/contents should be detected

  • signature algorithms - invalid sig/contents should be detected

  • compression

  • checking that errors are detected like:
    • image overwriting

    • missing images

    • invalid configurations

    • incorrect os/arch/type fields

    • empty data

    • images too large/small

    • invalid FDT (e.g. putting a random binary in instead)

  • default configuration selection

  • bootm command line parameters should have desired effect

  • run code coverage to make sure we are testing all the code

save_bootstage(ubman)

Save and restore bootstage around each test.

filesize(fname)

Get the size of a file

Args:

fname (str): Filename to check

Return:

int: Size of file in bytes

read_file(fname)

Read the contents of a file

Args:

fname (str): Filename to read

Return:

str: Contents of file

make_ramdisk(ubman, filename, text)

Make a sample ramdisk with test data

Returns:

str: Filename of ramdisk created

make_compressed(ubman, filename)

Compress a file using gzip

find_matching(text, match)

Find a match in a line of text, and return the unmatched line portion

This is used to extract a part of a line from some text. The match string is used to locate the line - we use the first line that contains that match text.

Once we find a match, we discard the match string itself from the line, and return what remains.

TODO: If this function becomes more generally useful, we could change it to use regex and return groups.

Args:

text (list of str): Text to check, one for each command issued match (str): String to search for

Return:

str: unmatched portion of line

Exceptions:

ValueError: If match is not found

Examples:

find_matching(['first line:10', 'second_line:20'], 'first line:')
-> '10'

find_matching(['first line:10', 'second_line:20'], 'second line')
-> raises ValueError

find_matching(['first line:10', 'second_line:20'], 'second_line:')
-> '20'

find_matching(['first line:10', 'second_line:20\nthird_line:30'],
              'third_line:')
-> '30'
check_equal(params, expected_fname, actual_fname, failure_msg)

Check that a file matches its expected contents

This is always used on out-buffers whose size is decided by the test script anyway, which in some cases may be larger than what we’re actually looking for. So it’s safe to truncate it to the size of the expected data.

Args:

params (dict): Parameters dict from which to get the filenames expected_fname (str): Key for filename containing expected contents actual_fname (str): Key for filename containing actual contents failure_msg (str): Message to print on failure

check_not_equal(params, expected_fname, actual_fname, failure_msg)

Check that a file does not match its expected contents

Args:

params (dict): Parameters dict from which to get the filenames expected_fname (str): Key for filename containing expected contents actual_fname (str): Key for filename containing actual contents failure_msg (str): Message to print on failure

fsetup(ubman)

A fixture to set up files and parameters for FIT tests

Args:

ubman (ConsoleBase): U-Boot fixture

Yields:

dict: Parameters needed by the test

prepare(ubman, fsetup, **kwargs)

Build a FIT with given params

Uses the base parameters to create a FIT and a script to test it,

For the use of eval here to evaluate f-strings, see:

https://stackoverflow.com/questions/42497625/how-to-postpone-defer-the-evaluation-of-f-strings

Args:

ubman (ConsoleBase): U-Boot fixture fsetup (dict): Information about the test setup kwargs (dict): Mapping from parameter name to an f-string which is evaluated to obtain the parameter value

Return:
tuple:

list of str: Commands to run for the test dict: Parameters used by the test str: Filename of the FIT that was created

test_fit_kernel_load(ubman, fsetup)

Test loading a FIT image with only a kernel

test_fit_kernel_fdt_load(ubman, fsetup)

Test loading a FIT image with a kernel and FDT

test_fit_kernel_fdt_ramdisk_load(ubman, fsetup)

Test loading a FIT image with kernel, FDT, and ramdisk

test_fit_loadables_load(ubman, fsetup)

Test a configuration with ‘loadables’ properties

test_fit_compressed_images_load(ubman, fsetup)

Test loading compressed kernel, FDT, and ramdisk images

test_fit_no_kernel_load(ubman, fsetup)

Test that ‘bootm’ fails when no kernel is specified

test_fit_no_kernel_load_only(ubman, fsetup)

Test that ‘bootm’ handles a load-only FIT

test_fit_no_kernel_second(ubman, fsetup)

Test that ‘bootm’ handles a load-only FIT and a second FIT

test_fit_kernel_noload_decomp_overflow(ubman, fsetup)

Test that an over-large compressed kernel_noload image is rejected

For a compressed ‘kernel_noload’ kernel, bootm_load_os() allocates a decompression buffer of ALIGN(image_len * 8, SZ_1M) and must bound the decompressor by that buffer. A kernel that decompresses to far more than eight times its compressed size must therefore fail with a decompression error instead of overflowing the buffer.

test_fit_kernel_noload_decomp_boundary(ubman, fsetup)

Test that decompression succeeds exactly at the buffer limit

For a compressed ‘kernel_noload’ kernel, bootm_load_os() allocates a decompression buffer of ALIGN(image_len * 8, SZ_1M). A kernel whose decompressed size equals that buffer exactly must succeed, guarding against an off-by-one rejection at the buffer limit.

pytestmark = [Mark(name='requiredtool', args=('dtc',), kwargs={}), Mark(name='buildconfigspec', args=('fit',), kwargs={}), Mark(name='boardspec', args=('sandbox',), kwargs={})]