diff options
Diffstat (limited to 'kernel/kapi')
| -rw-r--r-- | kernel/kapi/filesystem.tests.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp index efcb4fd3..f46c6bb8 100644 --- a/kernel/kapi/filesystem.tests.cpp +++ b/kernel/kapi/filesystem.tests.cpp @@ -12,7 +12,9 @@ #include <cstddef> #include <filesystem> #include <ranges> +#include <string> #include <string_view> +#include <utility> #include <vector> using namespace kstd::units_literals; @@ -339,4 +341,94 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_vfs_fixture, } } +SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_vfs_fixture, "Kapi filesystem with a mounted fat32 image", + "[kapi][filesystem][fat32]") +{ + auto const ext2_image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + auto const fat32_image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "fat32.img"; + + GIVEN("an ext2 root filesystem with a fat32 image mounted on /information") + { + REQUIRE(std::filesystem::exists(ext2_image_path)); + REQUIRE(std::filesystem::exists(fat32_image_path)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1", "test_img_module_2"}, + {ext2_image_path, fat32_image_path})); + REQUIRE(kapi::filesystem::mount("/dev/ram1", "/information")); + + auto const read_text = [](std::size_t fd, std::size_t chunk_size) { + auto text = std::string{}; + auto buffer = std::vector<std::byte>(chunk_size); + while (true) + { + auto const bytes_read = kapi::filesystem::read(fd, buffer); + REQUIRE(bytes_read); + if (*bytes_read == 0_B) + { + return text; + } + text.append(std::bit_cast<char *>(buffer.data()), bytes_read->value); + } + }; + + THEN("a file can be opened by its lowercase name, read and closed again") + { + auto const fd = kapi::filesystem::open("/information/hello.txt"); + REQUIRE(fd); + REQUIRE(read_text(*fd, 64) == "Hello World!"); + REQUIRE(kapi::filesystem::close(*fd)); + } + + THEN("a file can be read in small chunks through its file descriptor") + { + auto const fd = kapi::filesystem::open("/information/hello.txt"); + REQUIRE(fd); + REQUIRE(read_text(*fd, 5) == "Hello World!"); + REQUIRE(kapi::filesystem::close(*fd)); + } + + THEN("reading continues at a seeked position") + { + auto const fd = kapi::filesystem::open("/information/hello.txt"); + REQUIRE(fd); + REQUIRE(kapi::filesystem::seek(*fd, 6_B_off, kapi::filesystem::seek_origin::beginning) == 6_B); + REQUIRE(read_text(*fd, 16) == "World!"); + REQUIRE(kapi::filesystem::close(*fd)); + } + + THEN("the status of a file reports its type and size") + { + auto const status = kapi::filesystem::status("/information/hello.txt"); + REQUIRE(status); + REQUIRE(status->mode == std::to_underlying(kapi::filesystem::file_type::regular)); + REQUIRE(status->size == 12_B); + } + + THEN("the mounted root directory can be listed") + { + auto const directory = kapi::filesystem::open("/information"); + REQUIRE(directory); + + auto buffer = std::vector<kapi::filesystem::directory_entry>{10}; + REQUIRE(kapi::filesystem::read_directory(*directory, buffer) == 1); + REQUIRE(buffer[0].name == "HELLO.TXT"); + REQUIRE(kapi::filesystem::read_directory(*directory, buffer) == 0); + } + + THEN("writing to a file fails because the filesystem is read only") + { + auto const fd = kapi::filesystem::open("/information/hello.txt"); + REQUIRE(fd); + + auto const buffer = std::vector<std::byte>{std::byte{'X'}}; + REQUIRE(kapi::filesystem::write(*fd, buffer).error() == kstd::errc::read_only_file_system); + REQUIRE(kapi::filesystem::close(*fd)); + } + + THEN("opening a missing file fails") + { + REQUIRE(kapi::filesystem::open("/information/missing.txt").error() == kstd::errc::no_such_file_or_directory); + } + } +} + // NOLINTEND (readability-magic-numbers)
\ No newline at end of file |
