diff options
Diffstat (limited to 'kernel/kernel/filesystem/ext2/directory_iterator.tests.cpp')
| -rw-r--r-- | kernel/kernel/filesystem/ext2/directory_iterator.tests.cpp | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/kernel/kernel/filesystem/ext2/directory_iterator.tests.cpp b/kernel/kernel/filesystem/ext2/directory_iterator.tests.cpp new file mode 100644 index 00000000..20ef7009 --- /dev/null +++ b/kernel/kernel/filesystem/ext2/directory_iterator.tests.cpp @@ -0,0 +1,118 @@ +#include <kernel/filesystem/ext2/directory_iterator.hpp> + +#include <kernel/devices/storage.hpp> +#include <kernel/filesystem/device_inode.hpp> +#include <kernel/filesystem/ext2/filesystem.hpp> +#include <kernel/filesystem/ext2/inode.hpp> +#include <kernel/filesystem/mount.hpp> +#include <kernel/test_support/filesystem/storage_boot_module_fixture.hpp> + +#include <kstd/memory.hpp> + +#include <catch2/catch_test_macros.hpp> + +#include <algorithm> +#include <filesystem> +#include <string> +#include <vector> + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, + "Ext2 directory_iterator walks a real directory and terminates", "[filesystem][ext2][readdir]") +{ + auto const image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + + GIVEN("a mounted ext2 filesystem and its root directory") + { + REQUIRE(std::filesystem::exists(image_path)); + REQUIRE_NOTHROW(setup_modules_from_img({"test_img_module"}, {image_path})); + + auto boot_device = kernel::devices::storage::determine_boot_device(); + REQUIRE(boot_device != nullptr); + + auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device); + auto fs = kstd::make_shared<kernel::filesystem::ext2::filesystem>(); + auto mount = kernel::filesystem::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); + REQUIRE(mount); + + auto root = (*mount)->root_dentry()->inode(); + auto const & root_ext2_inode = static_cast<kernel::filesystem::ext2::inode const &>(*root); + + WHEN("iterating from begin to the default-constructed end sentinel") + { + auto names = std::vector<std::string>{}; + auto guard = 0; + + for (auto it = kernel::filesystem::ext2::directory_iterator{root_ext2_inode}; + it != kernel::filesystem::ext2::directory_iterator{}; ++it) + { + REQUIRE(guard++ < 64); // fails loudly on a non-terminating loop rather than hanging the suite + names.emplace_back(&it->name_start, it->name_len); + } + + THEN("iteration terminates on its own and finds the expected entries") + { + REQUIRE(guard < 64); + REQUIRE(std::ranges::find(names, ".") != names.end()); + REQUIRE(std::ranges::find(names, "..") != names.end()); + REQUIRE(std::ranges::find(names, "information") != names.end()); + } + } + } +} + +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, + "Ext2 directory_iterator satisfies the forward-iterator multi-pass guarantee", + "[filesystem][ext2][readdir]") +{ + auto const image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; + + GIVEN("an iterator positioned at the first entry of the root directory") + { + REQUIRE(std::filesystem::exists(image_path)); + REQUIRE_NOTHROW(setup_modules_from_img({"test_img_module"}, {image_path})); + + auto boot_device = kernel::devices::storage::determine_boot_device(); + REQUIRE(boot_device != nullptr); + + auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device); + auto fs = kstd::make_shared<kernel::filesystem::ext2::filesystem>(); + auto mount = kernel::filesystem::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); + REQUIRE(mount); + + auto root = (*mount)->root_dentry()->inode(); + auto const & root_ext2_inode = static_cast<kernel::filesystem::ext2::inode const &>(*root); + + auto original = kernel::filesystem::ext2::directory_iterator{root_ext2_inode}; + auto const first_name = std::string{&original->name_start, original->name_len}; + + WHEN("the iterator is copied, then only the original is advanced") + { + auto copy = original; + ++original; + + THEN("the copy still refers to the first entry, unaffected by advancing the original") + { + auto const copy_name = std::string{©->name_start, copy->name_len}; + REQUIRE(copy_name == first_name); + + auto const advanced_name = std::string{&original->name_start, original->name_len}; + REQUIRE(advanced_name != first_name); + } + } + } +} + +SCENARIO("Ext2 directory_iterator's default-constructed value is a valid, comparable end sentinel", + "[filesystem][ext2][readdir]") +{ + GIVEN("two independently default-constructed iterators") + { + auto first = kernel::filesystem::ext2::directory_iterator{}; + auto second = kernel::filesystem::ext2::directory_iterator{}; + + THEN("they compare equal to each other") + { + REQUIRE(first == second); + } + } +}
\ No newline at end of file |
