[Concept,09/12] test: fs: Add ext4l filesystem tests
Commit Message
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
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y += fs_basic.o
+obj-$(CONFIG_FS_EXT4L) += ext4l.o
new file mode 100644
@@ -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 });
new file mode 100644
@@ -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