From: Simon Glass <simon.glass@canonical.com> Add initial tests for the ext4l filesystem driver: - fs_test_ext4l_probe_norun: verifies the driver can probe and mount an ext4 filesystem - fs_test_ext4l_msgs_norun: verifies the ext4l_msgs env var causes mount messages to be printed The C tests use UTF_MANUAL flag and accept fs_image argument, following the pattern established by fs_basic.c. The Python wrapper creates an ext4 image and calls the C tests. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/fs/Makefile | 1 + test/fs/ext4l.c | 81 +++++++++++++++++++++++++++++ test/py/tests/test_fs/test_ext4l.py | 59 +++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 test/fs/ext4l.c create mode 100644 test/py/tests/test_fs/test_ext4l.py diff --git a/test/fs/Makefile b/test/fs/Makefile index 5899be8e667..a8fd1227a1d 100644 --- a/test/fs/Makefile +++ b/test/fs/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+ obj-y += fs_basic.o +obj-$(CONFIG_FS_EXT4L) += ext4l.o diff --git a/test/fs/ext4l.c b/test/fs/ext4l.c new file mode 100644 index 00000000000..e566c9e97b0 --- /dev/null +++ b/test/fs/ext4l.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for ext4l filesystem (Linux ext4 port) + * + * Copyright 2025 Canonical Ltd + * Written by Simon Glass <simon.glass@canonical.com> + */ + +#include <command.h> +#include <env.h> +#include <ext4l.h> +#include <fs.h> +#include <fs_legacy.h> +#include <u-boot/uuid.h> +#include <test/test.h> +#include <test/ut.h> +#include <test/fs.h> + +#define EXT4L_ARG_IMAGE 0 /* fs_image: path to filesystem image */ + +/** + * fs_test_ext4l_probe_norun() - Test probing an ext4l filesystem + * + * This test verifies that the ext4l driver can successfully probe and + * mount an ext4 filesystem image. + * + * Arguments: + * fs_image: Path to the ext4 filesystem image + */ +static int fs_test_ext4l_probe_norun(struct unit_test_state *uts) +{ + const char *fs_image = ut_str(EXT4L_ARG_IMAGE); + + ut_assertnonnull(fs_image); + ut_assertok(run_commandf("host bind 0 %s", fs_image)); + ut_assertok(fs_set_blk_dev("host", "0", FS_TYPE_ANY)); + + return 0; +} +FS_TEST_ARGS(fs_test_ext4l_probe_norun, UTF_SCAN_FDT | UTF_CONSOLE | UTF_MANUAL, + { "fs_image", UT_ARG_STR }); + +/** + * fs_test_ext4l_msgs_norun() - Test ext4l_msgs env var output + * + * This test verifies that setting ext4l_msgs=y causes mount messages + * to be printed when probing an ext4 filesystem. + * + * Arguments: + * fs_image: Path to the ext4 filesystem image + */ +static int fs_test_ext4l_msgs_norun(struct unit_test_state *uts) +{ + const char *fs_image = ut_str(EXT4L_ARG_IMAGE); + char uuid_str[UUID_STR_LEN + 1]; + u8 uuid[16]; + + ut_assertnonnull(fs_image); + ut_assertok(env_set("ext4l_msgs", "y")); + console_record_reset_enable(); + ut_assertok(run_commandf("host bind 0 %s", fs_image)); + ut_assertok(fs_set_blk_dev("host", "0", FS_TYPE_ANY)); + + /* Get the UUID and clear the env var now we have the output */ + ut_assertok(ext4l_get_uuid(uuid)); + uuid_bin_to_str(uuid, uuid_str, UUID_STR_FORMAT_STD); + ut_assertok(env_set("ext4l_msgs", NULL)); + + /* + * Check messages. The probe test runs first and doesn't unmount, + * so the journal needs recovery. Verify both messages. + */ + ut_assert_nextline("EXT4-fs (ext4l_mmc0): recovery complete"); + ut_assert_nextline("EXT4-fs (ext4l_mmc0): mounted filesystem %s r/w with ordered data mode. Quota mode: disabled.", + uuid_str); + ut_assert_console_end(); + + return 0; +} +FS_TEST_ARGS(fs_test_ext4l_msgs_norun, UTF_SCAN_FDT | UTF_CONSOLE | UTF_MANUAL, + { "fs_image", UT_ARG_STR }); diff --git a/test/py/tests/test_fs/test_ext4l.py b/test/py/tests/test_fs/test_ext4l.py new file mode 100644 index 00000000000..3b206293cbc --- /dev/null +++ b/test/py/tests/test_fs/test_ext4l.py @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2025 Canonical Ltd +# Written by Simon Glass <simon.glass@canonical.com> +# +# Test for ext4l filesystem driver + +""" +Test ext4l filesystem probing via C unit test. +""" + +import os +from subprocess import CalledProcessError, check_call + +import pytest + + +@pytest.mark.boardspec('sandbox') +class TestExt4l: + """Test ext4l filesystem operations.""" + + @pytest.fixture(scope='class') + def ext4_image(self, u_boot_config): + """Create an ext4 filesystem image for testing. + + Args: + u_boot_config (u_boot_config): U-Boot configuration. + + Yields: + str: Path to the ext4 image file. + """ + image_path = os.path.join(u_boot_config.persistent_data_dir, + 'ext4l_test.img') + try: + # Create a 64MB ext4 image + check_call(f'dd if=/dev/zero of={image_path} bs=1M count=64 2>/dev/null', + shell=True) + check_call(f'mkfs.ext4 -q {image_path}', shell=True) + except CalledProcessError: + pytest.skip('Failed to create ext4 image') + + yield image_path + + # Cleanup + if os.path.exists(image_path): + os.remove(image_path) + + def test_probe(self, ubman, ext4_image): + """Test that ext4l can probe an ext4 filesystem.""" + with ubman.log.section('Test ext4l probe'): + output = ubman.run_command( + f'ut -f fs fs_test_ext4l_probe_norun fs_image={ext4_image}') + assert 'failures: 0' in output + + def test_msgs(self, ubman, ext4_image): + """Test that ext4l_msgs env var produces mount messages.""" + with ubman.log.section('Test ext4l msgs'): + output = ubman.run_command( + f'ut -f fs fs_test_ext4l_msgs_norun fs_image={ext4_image}') + assert 'failures: 0' in output -- 2.43.0