Add automated pytest for the 9P filesystem testing directory listing
(ls) and file loading (load) over virtio-9p in QEMU ARM64. Also enable
the relevant configurations in qemu_arm64_defconfig.

Signed-off-by: Kuan-Wei Chiu <[email protected]>
---
 configs/qemu_arm64_defconfig |  3 ++
 test/py/tests/test_9p.py     | 82 ++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 test/py/tests/test_9p.py

diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig
index ae6dd770f3e..75b50eeb5ea 100644
--- a/configs/qemu_arm64_defconfig
+++ b/configs/qemu_arm64_defconfig
@@ -40,6 +40,7 @@ CONFIG_CMD_TPM=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_SPAWN=y
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_NET_9P=y
 CONFIG_AHCI=y
 CONFIG_SCSI_AHCI=y
 CONFIG_AHCI_PCI=y
@@ -73,6 +74,8 @@ CONFIG_SYSRESET_PSCI=y
 CONFIG_TPM2_MMIO=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_PCI=y
+CONFIG_VIRTIO_9P=y
+CONFIG_FS_9P=y
 CONFIG_MBEDTLS_LIB=y
 CONFIG_TPM=y
 CONFIG_TPM_PCR_ALLOCATE=y
diff --git a/test/py/tests/test_9p.py b/test/py/tests/test_9p.py
new file mode 100644
index 00000000000..7b3b17c8366
--- /dev/null
+++ b/test/py/tests/test_9p.py
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2026, Kuan-Wei Chiu <[email protected]>
+
+import os
+import pytest
+import utils
+import zlib
+
[email protected]("fs_9p")
[email protected]("cmd_virtio")
+def test_fs_9p(ubman):
+    """Test the 9P filesystem commands."""
+
+    test_file_name = "9p_test_small.txt"
+    test_file_content = b"9PFS_AUTOMATED_TEST_CONTENT_1234567890\n" * 10
+    test_file_size = len(test_file_content)
+    test_file_crc = zlib.crc32(test_file_content) & 0xffffffff
+    test_file_path = os.path.join(ubman.config.build_dir, test_file_name)
+
+    with open(test_file_path, "wb") as f:
+        f.write(test_file_content)
+
+    large_file_name = "9p_test_large.bin"
+    large_file_content = b"".join(bytes([i % 256]) for i in range(128 * 1024))
+    large_file_size = len(large_file_content)
+    large_file_crc = zlib.crc32(large_file_content) & 0xffffffff
+    large_file_path = os.path.join(ubman.config.build_dir, large_file_name)
+
+    with open(large_file_path, "wb") as f:
+        f.write(large_file_content)
+
+    sub_dir_name = "9p_subdir"
+    sub_dir_path = os.path.join(ubman.config.build_dir, sub_dir_name)
+    os.makedirs(sub_dir_path, exist_ok=True)
+    nested_file_name = "nested.txt"
+    nested_file_content = b"NESTED_FILE_DATA_OK\n"
+    nested_file_path = os.path.join(sub_dir_path, nested_file_name)
+
+    with open(nested_file_path, "wb") as f:
+        f.write(nested_file_content)
+
+    ubman.run_command("virtio scan")
+    addr = utils.find_ram_base(ubman)
+
+    output = ubman.run_command("ls 9p - /")
+    assert test_file_name in output
+    assert sub_dir_name in output
+
+    output = ubman.run_command("ls 9p rootfs /")
+    assert test_file_name in output
+    assert large_file_name in output
+
+    output = ubman.run_command("ls 9p 0 /")
+    assert test_file_name in output
+
+    output = ubman.run_command(f"ls 9p rootfs /{sub_dir_name}")
+    assert nested_file_name in output
+
+    output = ubman.run_command(f"size 9p rootfs /{test_file_name}")
+    output = ubman.run_command("printenv filesize")
+    assert f"filesize={test_file_size:x}" in output
+
+    output = ubman.run_command(f"load 9p rootfs {addr:x} /{test_file_name}")
+    assert f"{test_file_size} bytes read" in output
+
+    output = ubman.run_command(f"crc32 {addr:x} $filesize")
+    assert f"{test_file_crc:08x}" in output
+
+    output = ubman.run_command(f"load 9p rootfs {addr:x} /{large_file_name}")
+    assert f"{large_file_size} bytes read" in output
+
+    output = ubman.run_command(f"crc32 {addr:x} $filesize")
+    assert f"{large_file_crc:08x}" in output
+
+    output = ubman.run_command(f"load 9p rootfs {addr:x} 
/{sub_dir_name}/{nested_file_name}")
+    assert f"{len(nested_file_content)} bytes read" in output
+
+    output = ubman.run_command(f"load 9p rootfs {addr:x} 
/non_existent_file_9p.txt")
+    assert "bytes read" not in output
+
+    output = ubman.run_command("ls 9p invalid_tag /")
+    assert test_file_name not in output
-- 
2.55.0.897.gb25b4bd76c-goog

Reply via email to